X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmParser.cxx;h=871c8086f4b78cfcf61dd3f1380ba04d0343983d;hb=c38654db595b51f0295f607c51172dae56d1d65d;hp=9a2f98143eb823756b79099c77cbb143cb05cb82;hpb=4e44e1c7eee620443e3a3ada6ce4e0bda97494d9;p=gdcm.git diff --git a/src/gdcmParser.cxx b/src/gdcmParser.cxx index 9a2f9814..871c8086 100644 --- a/src/gdcmParser.cxx +++ b/src/gdcmParser.cxx @@ -1,8 +1,7 @@ -// gdcmHeader.cxx +// gdcmParser.cxx //----------------------------------------------------------------------------- -#include "gdcmParser.h" -#include "gdcmUtil.h" #include +#include // For nthos: #ifdef _MSC_VER @@ -19,6 +18,10 @@ #endif # include +#include "gdcmParser.h" +#include "gdcmUtil.h" +#include "gdcmDebug.h" + #define UI1_2_840_10008_1_2 "1.2.840.10008.1.2" #define UI1_2_840_10008_1_2_1 "1.2.840.10008.1.2.1" #define UI1_2_840_10008_1_2_2 "1.2.840.10008.1.2.2" @@ -64,6 +67,19 @@ // DL Delimiters // + // Other usefull abreviations : + // Radiographic view associated with Patient Position (0018,5100). + // Defined Terms: + // + // AP = Anterior/Posterior + // PA = Posterior/Anterior + // LL = Left Lateral + // RL = Right Lateral + // RLD = Right Lateral Decubitus + // LLD = Left Lateral Decubitus + // RLO = Right Lateral Oblique + // LLO = Left Lateral Oblique + //----------------------------------------------------------------------------- // Refer to gdcmParser::CheckSwap() const unsigned int gdcmParser::HEADER_LENGTH_TO_READ = 256; @@ -77,11 +93,12 @@ const unsigned int gdcmParser::MAX_SIZE_PRINT_ELEMENT_VALUE = 64; //----------------------------------------------------------------------------- // Constructor / Destructor + /** * \ingroup gdcmParser - * \brief - * @param InFilename - * @param exception_on_error + * \brief constructor + * @param inFilename + * @param exception_on_error whether we throw an exception or not * @param enable_sequences = true to allow the header * to be parsed *inside* the SeQuences, * when they have an actual length @@ -91,15 +108,15 @@ const unsigned int gdcmParser::MAX_SIZE_PRINT_ELEMENT_VALUE = 64; * with a FALSE value for the 'enable_sequence' param. * ('public elements' may be embedded in 'shadow Sequences') */ -gdcmParser::gdcmParser(const char *InFilename, +gdcmParser::gdcmParser(const char *inFilename, bool exception_on_error, bool enable_sequences, bool ignore_shadow) { enableSequences=enable_sequences; ignoreShadow =ignore_shadow; - SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE); - filename = InFilename; + SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE); + filename = inFilename; Initialise(); if ( !OpenFile(exception_on_error)) @@ -115,7 +132,7 @@ gdcmParser::gdcmParser(const char *InFilename, /** * \ingroup gdcmParser - * \brief + * \brief constructor * @param exception_on_error */ gdcmParser::gdcmParser(bool exception_on_error) { @@ -169,7 +186,7 @@ void gdcmParser::PrintPubDict(std::ostream & os) { /** * \ingroup gdcmParser - * \brief Prints The Dict Entries of THE shadow Dicom Dictionnry + * \brief Prints The Dict Entries of THE shadow Dicom Dictionnary * @return */ void gdcmParser::PrintShaDict(std::ostream & os) { @@ -238,7 +255,6 @@ bool gdcmParser::IsReadable(void) { * \ingroup gdcmParser * \brief Determines if the Transfer Syntax was already encountered * and if it corresponds to a ImplicitVRLittleEndian one. - * * @return True when ImplicitVRLittleEndian found. False in all other cases. */ bool gdcmParser::IsImplicitVRLittleEndianTransferSyntax(void) { @@ -257,7 +273,6 @@ bool gdcmParser::IsImplicitVRLittleEndianTransferSyntax(void) { * \ingroup gdcmParser * \brief Determines if the Transfer Syntax was already encountered * and if it corresponds to a ExplicitVRLittleEndian one. - * * @return True when ExplicitVRLittleEndian found. False in all other cases. */ bool gdcmParser::IsExplicitVRLittleEndianTransferSyntax(void) { @@ -276,7 +291,6 @@ bool gdcmParser::IsExplicitVRLittleEndianTransferSyntax(void) { * \ingroup gdcmParser * \brief Determines if the Transfer Syntax was already encountered * and if it corresponds to a DeflatedExplicitVRLittleEndian one. - * * @return True when DeflatedExplicitVRLittleEndian found. False in all other cases. */ bool gdcmParser::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) { @@ -295,7 +309,6 @@ bool gdcmParser::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) { * \ingroup gdcmParser * \brief Determines if the Transfer Syntax was already encountered * and if it corresponds to a Explicit VR Big Endian one. - * * @return True when big endian found. False in all other cases. */ bool gdcmParser::IsExplicitVRBigEndianTransferSyntax(void) { @@ -314,7 +327,7 @@ bool gdcmParser::IsExplicitVRBigEndianTransferSyntax(void) { * \ingroup gdcmParser * \brief returns the File Type * (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown) - * @return + * @return the FileType code */ FileType gdcmParser::GetFileType(void) { return(filetype); @@ -376,7 +389,8 @@ bool gdcmParser::CloseFile(void) { /** * \ingroup gdcmParser - * \brief + * \brief writes on disc all the Header Entries (Dicom Elements) + * of the Chained List * @param fp file pointer on an already open file * @param type type of the File to be written * (ACR-NEMA, ExplicitVR, ImplicitVR) @@ -426,7 +440,7 @@ bool gdcmParser::Write(FILE *fp, FileType type) { SetEntryLengthByNumber(20, 0x0002, 0x0010); } -/* TODO : rewrite later +/* TODO : rewrite later, if really usefull if ( (type == ImplicitVR) || (type == ExplicitVR) ) UpdateGroupLength(false,type); @@ -442,22 +456,28 @@ bool gdcmParser::Write(FILE *fp, FileType type) { * \ingroup gdcmParser * \brief Modifies the value of a given Header Entry (Dicom Element) * if it exists; Creates it with the given value if it doesn't + * \warning : adds the Header Entry to the HTable, NOT to the chained List * @param Value passed as a std::string - * @param Group - * @param Elem - * \return boolean + * @param Group group of the Entry + * @param Elem element of the Entry + * \return pointer to the created Header Entry + * NULL if creation failed */ -bool gdcmParser::ReplaceOrCreateByNumber(std::string Value, +gdcmHeaderEntry * gdcmParser::ReplaceOrCreateByNumber( + std::string Value, guint16 Group, - guint16 Elem ){ - if (CheckIfEntryExistByNumber(Group, Elem) == 0) { + guint16 Elem ){ + gdcmHeaderEntry* a; + a = GetHeaderEntryByNumber( Group, Elem); + if (a == NULL) { gdcmHeaderEntry *a =NewHeaderEntryByNumber(Group, Elem); if (a == NULL) - return false; + return NULL; AddHeaderEntry(a); } - SetEntryByNumber(Value, Group, Elem); - return(true); + //SetEntryByNumber(Value, Group, Elem); + a->SetValue(Value); + return(a); } /** @@ -465,31 +485,35 @@ bool gdcmParser::ReplaceOrCreateByNumber(std::string Value, * \brief Modifies the value of a given Header Entry (Dicom Element) * if it exists; Creates it with the given value if it doesn't * @param Value passed as a char* - * @param Group - * @param Elem - * \return boolean + * @param Group group of the Entry + * @param Elem element of the Entry + * \return pointer to the created Header Entry + * NULL if creation failed * */ -bool gdcmParser::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) { +gdcmHeaderEntry * gdcmParser::ReplaceOrCreateByNumber( + char* Value, + guint16 Group, + guint16 Elem ) { gdcmHeaderEntry* nvHeaderEntry=NewHeaderEntryByNumber(Group, Elem); if(!nvHeaderEntry) - return(false); + return(NULL); AddHeaderEntry(nvHeaderEntry); std::string v = Value; SetEntryByNumber(v, Group, Elem); - return(true); + return(nvHeaderEntry); } /** * \ingroup gdcmParser * \brief Set a new value if the invoked element exists * Seems to be useless !!! - * @param Value - * @param Group - * @param Elem + * @param Value new element value + * @param Group group of the Entry + * @param Elem element of the Entry * \return boolean */ bool gdcmParser::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) @@ -501,10 +525,11 @@ bool gdcmParser::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem //----------------------------------------------------------------------------- // Protected + /** * \ingroup gdcmParser * \brief Checks if a given Dicom Element exists - * \ within the H table + * 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 @@ -556,6 +581,7 @@ std::string gdcmParser::GetEntryVRByName(std::string tagName) { return elem->GetVR(); } + /** * \ingroup gdcmParser * \brief Searches within Header Entries (Dicom Elements) parsed with @@ -595,6 +621,21 @@ std::string gdcmParser::GetEntryVRByNumber(guint16 group, guint16 element) { return elem->GetVR(); } +/** + * \ingroup gdcmParser + * \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 of the searched tag. + * @param element Element of the searched tag. + * @return Corresponding element length; -2 if not found + */ +int gdcmParser::GetEntryLengthByNumber(guint16 group, guint16 element) { + gdcmHeaderEntry* elem = GetHeaderEntryByNumber(group, element); + if ( !elem ) + return -2; + return elem->GetLength(); +} /** * \ingroup gdcmParser * \brief Sets the value (string) of the Header Entry (Dicom Element) @@ -629,7 +670,7 @@ bool gdcmParser::SetEntryByNumber(std::string content, if ( ! tagHT.count(key)) return false; int l = content.length(); - if(l%2) // Odd length are padded with a space (020H). + if(l%2) // Non even length are padded with a space (020H). { l++; content = content + '\0'; @@ -669,20 +710,20 @@ bool gdcmParser::SetEntryByNumber(std::string content, * through it's (group, element) and modifies it's length with * the given value. * \warning Use with extreme caution. - * @param length new length to substitute with - * @param group group of the entry to modify - * @param element element of the Entry to modify - * @return 1 on success, 0 otherwise. + * @param l new length to substitute with + * @param group group of the Entry to modify + * @param element element of the Entry to modify + * @return true on success, false otherwise. */ -bool gdcmParser::SetEntryLengthByNumber(guint32 length, +bool gdcmParser::SetEntryLengthByNumber(guint32 l, guint16 group, guint16 element) { TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHT.count(key)) return false; - if (length%2) length++; // length must be even - ( ((tagHT.equal_range(key)).first)->second )->SetLength(length); + if (l%2) l++; // length must be even + ( ((tagHT.equal_range(key)).first)->second )->SetLength(l); return true ; } @@ -690,9 +731,9 @@ bool gdcmParser::SetEntryLengthByNumber(guint32 length, /** * \ingroup gdcmParser * \brief Gets (from Header) the offset of a 'non string' element value - * \ (LoadElementValues has already be executed) - * @param Group - * @param Elem + * (LoadElementValues has already be executed) + * @param Group group of the Entry + * @param Elem element of the Entry * @return File Offset of the Element Value */ size_t gdcmParser::GetEntryOffsetByNumber(guint16 Group, guint16 Elem) @@ -710,9 +751,9 @@ size_t gdcmParser::GetEntryOffsetByNumber(guint16 Group, guint16 Elem) /** * \ingroup gdcmParser * \brief Gets (from Header) a 'non string' element value - * \ (LoadElementValues has already be executed) - * @param Group - * @param Elem + * (LoadElementValues has already be executed) + * @param Group group of the Entry + * @param Elem element of the Entry * @return Pointer to the 'non string' area */ void * gdcmParser::GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem) @@ -731,8 +772,8 @@ void * gdcmParser::GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem) * \ingroup gdcmParser * \brief Loads (from disk) the element content * when a string is not suitable - * @param Group - * @param Elem + * @param Group group of the Entry + * @param Elem element of the Entry */ void *gdcmParser::LoadEntryVoidArea(guint16 Group, guint16 Elem) { @@ -779,8 +820,8 @@ bool gdcmParser::SetEntryVoidAreaByNumber(void * area, /** * \ingroup gdcmParser - * \brief Update the entries with the shadow dictionary. Only odd entries are - * analized + * \brief Update the entries with the shadow dictionary. + * Only non even entries are analyzed */ void gdcmParser::UpdateShaEntries(void) { gdcmDictEntry *entry; @@ -840,7 +881,7 @@ void gdcmParser::UpdateShaEntries(void) { /** * \ingroup gdcmParser * \brief retrieves a Dicom Element (the first one) using (group, element) - * \ warning (group, element) IS NOT an identifier inside the Dicom Header + * \warning (group, element) IS NOT an identifier inside the Dicom Header * 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) @@ -850,7 +891,7 @@ void gdcmParser::UpdateShaEntries(void) { */ gdcmHeaderEntry* gdcmParser::GetHeaderEntryByNumber(guint16 group, guint16 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); + TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHT.count(key)) return NULL; return tagHT.find(key)->second; @@ -993,17 +1034,14 @@ void gdcmParser::UpdateGroupLength(bool SkipSequence, FileType type) { /** * \ingroup gdcmParser * \brief writes on disc according to the requested format - * \ (ACR-NEMA, ExplicitVR, ImplicitVR) the image - * \ warning does NOT add the missing elements in the header : - * \ it's up to the user doing it ! - * \ (function CheckHeaderCoherence to be written) - * \ warning DON'T try, right now, to write a DICOM image - * \ from an ACR Header (meta elements will be missing!) + * (ACR-NEMA, ExplicitVR, ImplicitVR) ONE + * gdcmHeaderEntry + * @param tag pointer on the gdcmHeaderEntry to be written * @param type type of the File to be written * (ACR-NEMA, ExplicitVR, ImplicitVR) * @param _fp already open file pointer */ -void gdcmParser::WriteEntries(FILE *_fp,FileType type) +void gdcmParser::WriteEntry(gdcmHeaderEntry *tag, FILE *_fp,FileType type) { guint16 gr, el; guint32 lgr; @@ -1015,83 +1053,71 @@ void gdcmParser::WriteEntries(FILE *_fp,FileType type) guint16 valZero =0; void *voidArea; std::vector tokens; - - // TODO : function CheckHeaderCoherence to be written - - // uses now listEntries to iterate, not TagHt! - // - // pb : gdcmParser.Add does NOT update listEntries - // TODO : find a trick (in STL?) to do it, at low cost ! void *ptr; - + int ff=0xffffffff; // TODO (?) tester les echecs en ecriture (apres chaque fwrite) int compte =0; - - for (ListTag::iterator tag2=listEntries.begin(); - tag2 != listEntries.end(); - ++tag2) - { + itsTimeToWritePixels = false; + + gr = tag->GetGroup(); + el = tag->GetElement(); + lgr = tag->GetReadLength(); + val = tag->GetValue().c_str(); + vr = tag->GetVR(); + voidArea = tag->GetVoidArea(); + // === Deal with the length // -------------------- - if(((*tag2)->GetLength())%2==1) - { - (*tag2)->SetValue((*tag2)->GetValue()+"\0"); - (*tag2)->SetLength((*tag2)->GetLength()+1); + if((tag->GetLength())%2==1) + { + tag->SetValue(tag->GetValue()+"\0"); + tag->SetLength(tag->GetReadLength()+1); } - - gr = (*tag2)->GetGroup(); - el = (*tag2)->GetElement(); - lgr = (*tag2)->GetReadLength(); - val = (*tag2)->GetValue().c_str(); - vr = (*tag2)->GetVR(); - voidArea = (*tag2)->GetVoidArea(); if ( type == ACR ) { - if (gr < 0x0008) continue; // ignore pure DICOM V3 groups - if (gr %2) continue; // ignore shadow groups - if (vr == "SQ" ) continue; // ignore Sequences + if (gr < 0x0008) return; // ignore pure DICOM V3 groups + if (gr %2) return; // ignore shadow groups + if (vr == "SQ" ) return; // ignore Sequences // TODO : find a trick to *skip* the SeQuences ! // Not only ignore the SQ element - if (gr == 0xfffe ) continue; // ignore delimiters + if (gr == 0xfffe ) return; // ignore delimiters } fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element - // if ( (type == ExplicitVR) && (gr <= 0x0002) ) // ?!? < 2 - if ( (type == ExplicitVR) || (type == DICOMDIR) ) - { + if ( (type == ExplicitVR) || (type == DICOMDIR) ) { // EXPLICIT VR guint16 z=0, shortLgr; - if (vr == "unkn") - { // Unknown was 'written' - shortLgr=lgr; + + if (gr == 0xfffe) { // NO Value Representation for 'delimiters' + // no length : write ffffffff + + // special patch to make some MR PHILIPS + if (el == 0x0000) return; // images e-film readable // see gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm + // from Hospital Guy de Chauliac, + // Montpellier + // we just ignore spurious fffe|0000 tag ! + + fwrite (&ff,(size_t)4 ,(size_t)1 ,_fp); + return; // NO value for 'delimiters' + } + + shortLgr=lgr; + if (vr == "unkn") { // Unknown was 'written' + // deal with Little Endian fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp); fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp); - } - else - { - if (gr != 0xfffe) - { // NO value for 'delimiters' - if (vr == "unkn") // Unknown was 'written' - fwrite(&z,(size_t)2 ,(size_t)1 ,_fp); - else - fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp); - } - - if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") || gr == 0xfffe) - { - if (gr != 0xfffe) + } else { + fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp); + if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ){ fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp); fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); - } - else - { - shortLgr=lgr; - fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp); - } + } else { + fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp); + } } } else // IMPLICIT VR @@ -1101,19 +1127,19 @@ void gdcmParser::WriteEntries(FILE *_fp,FileType type) // === Deal with the value // ------------------- - if (vr == "SQ") continue; // no "value" to write for the SEQuences - if (gr == 0xfffe)continue; + if (vr == "SQ") return; // no "value" to write for the SEQuences + if (gr == 0xfffe)return; // no "value" to write for the delimiters if (voidArea != NULL) { // there is a 'non string' LUT, overlay, etc fwrite ( voidArea,(size_t)lgr ,(size_t)1 ,_fp); // Elem value - continue; + return; } if (vr == "US" || vr == "SS") { tokens.erase(tokens.begin(),tokens.end()); // clean any previous value - Tokenize ((*tag2)->GetValue(), tokens, "\\"); + Tokenize (tag->GetValue(), tokens, "\\"); for (unsigned int i=0; iGetValue(), tokens, "\\"); + Tokenize (tag->GetValue(), tokens, "\\"); for (unsigned int i=0; isecond,_fp,type); + if (itsTimeToWritePixels) + break; } } @@ -1389,7 +1476,7 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry *Entry) { } if( (vr == "UI") ) // Because of correspondance with the VR dic - Entry->SetValue(NewValue.c_str()); // ??? JPR ??? + Entry->SetValue(NewValue.c_str()); else Entry->SetValue(NewValue); } @@ -1397,10 +1484,11 @@ void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry *Entry) { /** * \ingroup gdcmParser * \brief add a new Dicom Element pointer to - * the H Table and to the chained List + * the H Table and at the end of the chained List * \warning push_bash in listEntries ONLY during ParseHeader - * \TODO something to allow further Elements addition, - * \ when position to be taken care of + * \todo something to allow further Elements addition, + * (at their right place in the chained list) + * when position to be taken care of * @param newHeaderEntry */ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry *newHeaderEntry) { @@ -1411,19 +1499,18 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry *newHeaderEntry) { /** * \ingroup gdcmParser - * \brief - * @param Entry Header Entry whose length of the value shall be loaded. - - * @return + * \brief Find the value Length of the passed Header Entry + * @param Entry Header Entry whose length of the value shall be loaded. */ void gdcmParser::FindHeaderEntryLength (gdcmHeaderEntry *Entry) { guint16 element = Entry->GetElement(); guint16 group = Entry->GetGroup(); std::string vr = Entry->GetVR(); guint16 length16; + if( (element == NumPixel) && (group == GrPixel) ) { - dbg.SetDebug(-1); + dbg.SetDebug(GDCM_DEBUG); dbg.Verbose(2, "gdcmParser::FindLength: ", "we reached (GrPixel,NumPixel)"); } @@ -1512,18 +1599,18 @@ void gdcmParser::AddHeaderEntry(gdcmHeaderEntry *newHeaderEntry) { // Actually, length= 0xffff means that we deal with // Unknown Sequence Length } - FixHeaderEntryFoundLength(Entry, (guint32)length16); return; } else { - // Either implicit VR or a non DICOM conformal (see not below) explicit + // Either implicit VR or a non DICOM conformal (see note below) explicit // VR that ommited the VR of (at least) this element. Farts happen. // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25 // on Data elements "Implicit and Explicit VR Data Elements shall // not coexist in a Data Set and Data Sets nested within it".] // Length is on 4 bytes. + FixHeaderEntryFoundLength(Entry, ReadInt32()); return; } @@ -1571,8 +1658,8 @@ void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *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 - * @param vr + * @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 */ @@ -1778,8 +1865,10 @@ void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry *Entry, guint32 Found guint16 el =Entry->GetElement(); if (FoundLength%2) { - std::cout << "Warning : Tag with uneven length " << FoundLength - << " in x(" << std::hex << gr << "," << el <<")" << std::dec << std::endl; + std::ostringstream s; + s << "Warning : Tag with uneven length " << FoundLength + << " in x(" << std::hex << gr << "," << el <<")" << std::dec; + dbg.Verbose(0,s.str().c_str()); } // Sorry for the patch! @@ -1812,29 +1901,20 @@ void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry *Entry, guint32 Found } // a SeQuence Element is beginning - // Let's forget it's length - // (we want to 'go inside') - - // Pb : *normaly* fffe|e000 is just a marker, its length *should be* zero - // in gdcm-MR-PHILIPS-16-Multi-Seq.dcm we find lengthes as big as 28800 - // if we set the length to zero IsHeaderEntryAnInteger() breaks... - // if we don't, we lost 28800 characters from the Header :-( - + // fffe|e000 is just a marker, its length *should be* zero else if(Entry->GetGroup() == 0xfffe) { - // sometimes, length seems to be wrong - FoundLength =0; // some more clever checking to be done ! - // I give up! - // only gdcm-MR-PHILIPS-16-Multi-Seq.dcm - // causes troubles :-( - } - + // *normally, fffe|0000 doesn't exist ! + if( Entry->GetElement() != 0x0000 ) // gdcm-MR-PHILIPS-16-Multi-Seq.dcm + // causes extra troubles :-( + FoundLength =0; + } Entry->SetUsableLength(FoundLength); } /** * \ingroup gdcmParser - * \brief Apply some heuristics to predict wether the considered + * \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. * @return The result of the heuristical predicate. @@ -1877,13 +1957,13 @@ bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry *Entry) { return false; } - /** * \ingroup gdcmParser - * \brief - * + * \brief Find the Length till the next sequence delimiter + * \warning NOT end user intended method ! * @return */ + guint32 gdcmParser::FindHeaderEntryLengthOB(void) { // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data. guint16 g; @@ -1901,7 +1981,7 @@ bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry *Entry) { return 0; TotalLength += 4; // We even have to decount the group and element - if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ + if ( g != 0xfffe && g!=0xb00c ) //for bogus header { char msg[100]; // for sprintf. Sorry sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n); @@ -1909,7 +1989,7 @@ bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry *Entry) { errno = 1; return 0; } - if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header */ + if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) // for bogus header FoundSequenceDelimiter = true; else if ( n != 0xe000 ) { @@ -1932,8 +2012,7 @@ bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry *Entry) { /** * \ingroup gdcmParser * \brief Reads a supposed to be 16 Bits integer - * \ (swaps it depending on processor endianity) - * + * (swaps it depending on processor endianity) * @return read value */ guint16 gdcmParser::ReadInt16(void) { @@ -1954,8 +2033,7 @@ guint16 gdcmParser::ReadInt16(void) { /** * \ingroup gdcmParser * \brief Reads a supposed to be 32 Bits integer - * \ (swaps it depending on processor endianity) - * + * (swaps it depending on processor endianity) * @return read value */ guint32 gdcmParser::ReadInt32(void) { @@ -1975,8 +2053,8 @@ guint32 gdcmParser::ReadInt32(void) { /** * \ingroup gdcmParser - * \brief - * + * \brief skips bytes inside the source file + * \warning NOT end user intended method ! * @return */ void gdcmParser::SkipBytes(guint32 NBytes) { @@ -1986,7 +2064,8 @@ void gdcmParser::SkipBytes(guint32 NBytes) { /** * \ingroup gdcmParser - * \brief + * \brief Loads all the needed Dictionaries + * \warning NOT end user intended method ! */ void gdcmParser::Initialise(void) { @@ -2181,7 +2260,8 @@ bool gdcmParser::CheckSwap() { /** * \ingroup gdcmParser - * \brief + * \brief Restore the unproperly loaded values i.e. the group, the element + * and the dictionary entry depending on them. */ void gdcmParser::SwitchSwapToBigEndian(void) { @@ -2208,7 +2288,7 @@ void gdcmParser::SwitchSwapToBigEndian(void) /** * \ingroup gdcmParser - * \brief + * \brief during parsing, Header Elements too long are not loaded in memory * @param NewSize */ void gdcmParser::SetMaxSizeLoadEntry(long NewSize) @@ -2226,8 +2306,9 @@ void gdcmParser::SetMaxSizeLoadEntry(long NewSize) /** * \ingroup gdcmParser - * \brief - * \warning TODO : not yet usable + * \brief Header Elements too long will not be printed + * \warning + * \todo : not yet usable * (see MAX_SIZE_PRINT_ELEMENT_VALUE * in gdcmHeaderEntry gdcmLoadEntry) * @@ -2325,15 +2406,15 @@ gdcmHeaderEntry *gdcmParser::ReadNextHeaderEntry(void) { // header parsing has to be considered as finished. return (gdcmHeaderEntry *)0; -/* Pb : how to propagate the element length (used in SkipHeaderEntry) +// Pb : how to propagate the element length (used in SkipHeaderEntry) // direct call to SkipBytes ? - if (ignoreShadow == 1 && g%2 ==1) //JPR +// if (ignoreShadow == 1 && g%2 ==1) // if user wants to skip shadow groups // and current element *is* a shadow element // we don't create anything - return (gdcmHeaderEntry *)1; // to tell caller it's NOT finished -*/ +// return (gdcmHeaderEntry *)1; // to tell caller it's NOT finished + NewEntry = NewHeaderEntryByNumber(g, n); FindHeaderEntryVR(NewEntry); FindHeaderEntryLength(NewEntry); @@ -2373,7 +2454,7 @@ gdcmHeaderEntry *gdcmParser::NewHeaderEntryByName(std::string Name) * \ingroup gdcmParser * \brief Request a new virtual dict entry to the dict set * @param group group of the underlying DictEntry - * @param elem element of the underlying DictEntry + * @param element element of the underlying DictEntry * @param vr VR of the underlying DictEntry * @param fourth owner group * @param name english name