X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=0c4507338b017a15dcef0edde0f0c0f42f1a7bb7;hb=9862070436bb6cee0fa3afd04a86d7b5888c8f72;hp=508eb5d436b1e8ca34a312bcdd3cd40cd0bd4cdd;hpb=e9d0fe99cef1e82bbc29c6dd5f65f7c1ccbd3412;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 508eb5d4..0c450733 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/06/17 12:36:07 $ - Version: $Revision: 1.246 $ + Date: $Date: 2005/07/07 13:55:39 $ + Version: $Revision: 1.261 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -31,6 +31,8 @@ #include #include #include +#include // for isdigit +#include // for atoi namespace gdcm { @@ -77,7 +79,7 @@ Document::Document( std::string const &fileName ) SwapCode = 1234; Filetype = ExplicitVR; Group0002Parsed = false; - LoadMode = 0x00000000; // Load everything + LoadMode = 0x00000000; // Load everything, later // Load will set it to true if sucessfull IsDocumentAlreadyLoaded = false; @@ -104,16 +106,25 @@ Document::~Document () */ bool Document::Load( std::string const &fileName ) { - // We should clean out anything that already exists. - // Check IsDocumentAlreadyLoaded to be sure. - if( IsDocumentAlreadyLoaded ) - { + if ( IsDocumentAlreadyLoaded ) + { + // time waste hunting + // if ( Filename == fileName ) + // { + // gdcmWarningMacro( "The file was already parsed inside this " + // << "gdcm::Document (its name is: " + // << Filename.c_str() ); + // return true; + // } + gdcmWarningMacro( "A file was already parsed inside this " << "gdcm::Document (previous name was: " << Filename.c_str() << ". New name is :" << fileName ); - // todo : clean out the 'Document' - // Should we call ClearEntry() on the parent object ?!? + // clean out the Entries, if already parsed + // (probabely a mistake from the user) + + ClearEntry(); } Filename = fileName; @@ -151,7 +162,9 @@ bool Document::Load( std::string const &fileName ) lgt -= beg; // remaining length to parse - ParseDES( this, beg, lgt, false); // Loading is done during parsing + // Recursive call. + // Loading is done during parsing + ParseDES( this, beg, lgt, false); // delim_mode is first defaulted to false if ( IsEmpty() ) { @@ -167,10 +180,14 @@ bool Document::Load( std::string const &fileName ) // Load 'non string' values std::string PhotometricInterpretation = GetEntryValue(0x0028,0x0004); - if( PhotometricInterpretation == "PALETTE COLOR " ) + if ( PhotometricInterpretation == "PALETTE COLOR " ) { - LoadEntryBinArea(0x0028,0x1200); // gray LUT - /// FIXME FIXME FIXME + // FIXME + // Probabely this line should be outside the 'if' + // Try to find an image sample holding a 'gray LUT' + LoadEntryBinArea(0x0028,0x1200); // gray LUT + + /// FIXME /// The tags refered by the three following lines used to be CORRECTLY /// defined as having an US Value Representation in the public /// dictionary. BUT the semantics implied by the three following @@ -180,7 +197,7 @@ bool Document::Load( std::string const &fileName ) /// 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 - /// whether 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 @@ -195,16 +212,32 @@ bool Document::Load( std::string const &fileName ) LoadEntryBinArea(0x0028,0x1222); // Segmented Blue Palette Color LUT Data LoadEntryBinArea(0x0028,0x1223); - } + } + //FIXME later : how to use it? - LoadEntryBinArea(0x0028,0x3006); //LUT Data (CTX dependent) + SeqEntry *modLutSeq = GetSeqEntry(0x0028,0x3000); + if ( modLutSeq !=0 ) + { + SQItem *sqi= modLutSeq->GetFirstSQItem(); + if ( sqi != 0 ) + { + BinEntry *b = sqi->GetBinEntry(0x0028,0x3006); + if ( b != 0 ) + { + if ( b->GetLength() != 0 ) + { + LoadEntryBinArea(b); //LUT Data (CTX dependent) + } + } + } + } CloseFile(); // ---------------------------- // Specific code to allow gdcm to read ACR-LibIDO formated images // Note: ACR-LibIDO is an extension of the ACR standard that was - // used at CREATIS. For the time being (say a couple years) + // used at CREATIS. For the time being (say a couple of years) // we keep this kludge to allow CREATIS users // reading their old images. // @@ -273,7 +306,7 @@ bool Document::SetShaDict(DictKey const &dictName) */ bool Document::IsReadable() { - if( Filetype == Unknown) + if ( Filetype == Unknown ) { gdcmWarningMacro( "Wrong filetype"); return false; @@ -456,14 +489,14 @@ std::ifstream *Document::OpenFile() return 0; } - if(Fp) + if ( Fp ) { gdcmWarningMacro( "File already open: " << Filename.c_str()); CloseFile(); } Fp = new std::ifstream(Filename.c_str(), std::ios::in | std::ios::binary); - if( ! *Fp ) + if ( ! *Fp ) { // Don't user gdcmErrorMacro : // a spurious message will appear when you use, for instance @@ -479,14 +512,14 @@ std::ifstream *Document::OpenFile() uint16_t zero = 0; Fp->read((char*)&zero, (size_t)2); - if( Fp->eof() ) + if ( Fp->eof() ) { CloseFile(); return 0; } //-- ACR or DICOM with no Preamble; may start with a Shadow Group -- - if( + if ( zero == 0x0001 || zero == 0x0100 || zero == 0x0002 || zero == 0x0200 || zero == 0x0003 || zero == 0x0300 || zero == 0x0004 || zero == 0x0400 || zero == 0x0005 || zero == 0x0500 || zero == 0x0006 || zero == 0x0600 || @@ -502,12 +535,12 @@ std::ifstream *Document::OpenFile() Fp->seekg(126L, std::ios::cur); char dicm[4] = {' ',' ',' ',' '}; Fp->read(dicm, (size_t)4); - if( Fp->eof() ) + if ( Fp->eof() ) { CloseFile(); return 0; } - if( memcmp(dicm, "DICM", 4) == 0 ) + if ( memcmp(dicm, "DICM", 4) == 0 ) { HasDCMPreamble = true; return Fp; @@ -526,7 +559,7 @@ std::ifstream *Document::OpenFile() */ bool Document::CloseFile() { - if( Fp ) + if ( Fp ) { Fp->close(); delete Fp; @@ -590,7 +623,7 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) return; BinEntry *binElement = dynamic_cast(docElement); - if( !binElement ) + if ( !binElement ) return; LoadEntryBinArea(binElement); @@ -603,11 +636,11 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) */ void Document::LoadEntryBinArea(BinEntry *elem) { - if(elem->GetBinArea()) + if (elem->GetBinArea() ) return; bool openFile = !Fp; - if(openFile) + if ( openFile ) OpenFile(); size_t o =(size_t)elem->GetOffset(); @@ -615,14 +648,14 @@ void Document::LoadEntryBinArea(BinEntry *elem) size_t l = elem->GetLength(); uint8_t *a = new uint8_t[l]; - if( !a ) + if ( !a ) { gdcmWarningMacro( "Cannot allocate BinEntry content"); return; } Fp->read((char*)a, l); - if( Fp->fail() || Fp->eof()) + if ( Fp->fail() || Fp->eof() ) { delete[] a; return; @@ -630,7 +663,7 @@ void Document::LoadEntryBinArea(BinEntry *elem) elem->SetBinArea(a); - if(openFile) + if ( openFile ) CloseFile(); } @@ -642,7 +675,7 @@ void Document::LoadEntryBinArea(BinEntry *elem) */ void Document::LoadDocEntrySafe(DocEntry *entry) { - if(Fp) + if ( Fp ) { long PositionOnEntry = Fp->tellg(); LoadDocEntry(entry); @@ -662,11 +695,11 @@ bool Document::operator<(Document &document) // Patient Name std::string s1 = GetEntryValue(0x0010,0x0010); std::string s2 = document.GetEntryValue(0x0010,0x0010); - if(s1 < s2) + if (s1 < s2) { return true; } - else if( s1 > s2 ) + else if ( s1 > s2 ) { return false; } @@ -692,7 +725,7 @@ bool Document::operator<(Document &document) { return true; } - else if( s1 > s2 ) + else if ( s1 > s2 ) { return false; } @@ -705,7 +738,7 @@ bool Document::operator<(Document &document) { return true; } - else if( s1 > s2 ) + else if ( s1 > s2 ) { return false; } @@ -731,7 +764,7 @@ uint16_t Document::ReadInt16() { throw FormatError( "Document::ReadInt16()", " file error." ); } - if( Fp->eof() ) + if ( Fp->eof() ) { throw FormatError( "Document::ReadInt16()", "EOF." ); } @@ -753,7 +786,7 @@ uint32_t Document::ReadInt32() { throw FormatError( "Document::ReadInt32()", " file error." ); } - if( Fp->eof() ) + if ( Fp->eof() ) { throw FormatError( "Document::ReadInt32()", "EOF." ); } @@ -790,15 +823,15 @@ int Document::ComputeGroup0002Length( FileType filetype ) { gr = entry->GetGroup(); - if( gr == 0x0002 ) + if ( gr == 0x0002 ) { found0002 = true; - if( entry->GetElement() != 0x0000 ) + if ( entry->GetElement() != 0x0000 ) { vr = entry->GetVR(); - if( filetype == ExplicitVR ) + if ( filetype == ExplicitVR ) { if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") || (vr == "UT") ) { @@ -832,9 +865,9 @@ void Document::Initialize() /** * \brief Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries) - * @param set DocEntrySet we are going to parse ('zero level' or a SQItem) + * @param set DocEntrySet we are going to parse ('zero level' or a SQItem) * @param offset start of parsing - * @param l_max length to parse + * @param l_max length to parse (meaningless when we are in 'delimitor mode') * @param delim_mode : whether we are in 'delimitor mode' (l=0xffffff) or not */ void Document::ParseDES(DocEntrySet *set, long offset, @@ -846,6 +879,7 @@ void Document::ParseDES(DocEntrySet *set, long offset, SeqEntry *newSeqEntry; VRKey vr; bool used; + bool delim_mode_intern = delim_mode; while (true) { @@ -854,7 +888,6 @@ void Document::ParseDES(DocEntrySet *set, long offset, break; } - used = true; newDocEntry = ReadNextDocEntry( ); if ( !newDocEntry ) @@ -862,15 +895,16 @@ void Document::ParseDES(DocEntrySet *set, long offset, break; } - vr = newDocEntry->GetVR(); + used = true; newValEntry = dynamic_cast(newDocEntry); newBinEntry = dynamic_cast(newDocEntry); - newSeqEntry = dynamic_cast(newDocEntry); - if ( newValEntry || newBinEntry ) + if ( newValEntry || newBinEntry ) { + //////////////////////////// ContentEntry if ( newBinEntry ) { + vr = newDocEntry->GetVR(); if ( Filetype == ExplicitVR && !Global::GetVR()->IsVROfBinaryRepresentable(vr) ) { @@ -882,6 +916,7 @@ 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 ( dynamic_cast< Document* > ( set ) ) @@ -891,20 +926,26 @@ void Document::ParseDES(DocEntrySet *set, long offset, // but when "this" is a SQItem, we are inserting this new // valEntry in a sequence item, and the key has the // generalized form (refer to \ref BaseTagKey): - if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) + + // time waste hunting + //if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) + //{ + // newBinEntry->SetKey( parentSQItem->GetBaseTagKey() + // + newBinEntry->GetKey() ); + //} + + if ( !set->AddEntry( newBinEntry ) ) { - newBinEntry->SetKey( parentSQItem->GetBaseTagKey() - + newBinEntry->GetKey() ); + gdcmWarningMacro( "in ParseDES : cannot add a BinEntry " + << newBinEntry->GetKey() ); + used=false; } - - LoadDocEntry( newBinEntry ); - if( !set->AddEntry( newBinEntry ) ) + else { - //Expect big troubles if here - //delete newBinEntry; - used=false; + // Load only if we can add (not a duplicate key) + LoadDocEntry( newBinEntry ); } - } + } // end BinEntry else { /////////////////////// ValEntry @@ -918,14 +959,13 @@ void Document::ParseDES(DocEntrySet *set, long offset, // ...but when "set" is a SQItem, we are inserting this new // valEntry in a sequence item. Hence the key has the // generalized form (refer to \ref BaseTagKey): - if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) - { - newValEntry->SetKey( parentSQItem->GetBaseTagKey() - + newValEntry->GetKey() ); - } - - LoadDocEntry( newValEntry ); - bool delimitor=newValEntry->IsItemDelimitor(); + + // time waste hunting + //if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) + //{ + // newValEntry->SetKey( parentSQItem->GetBaseTagKey() + // + newValEntry->GetKey() ); + //} if ( LoadMode & NO_SHADOW ) // User asked to skip, if possible, // shadow groups ( if possible : @@ -948,22 +988,24 @@ void Document::ParseDES(DocEntrySet *set, long offset, } } - if( !set->AddEntry( newValEntry ) ) + if ( !set->AddEntry( newValEntry ) ) { - // If here expect big troubles - // delete newValEntry; //otherwise mem leak + gdcmWarningMacro( "in ParseDES : cannot add a ValEntry " + << newValEntry->GetKey() ); used=false; } - - if (delimitor) + else { - if(!used) - delete newDocEntry; - break; + // Load only if we can add (not a duplicate key) + LoadDocEntry( newValEntry ); } - if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) + + bool delimitor=newValEntry->IsItemDelimitor(); + + if ( delimitor || + (!delim_mode && ((long)(Fp->tellg())-offset) >= l_max) ) { - if(!used) + if ( !used ) delete newDocEntry; break; } @@ -974,29 +1016,43 @@ void Document::ParseDES(DocEntrySet *set, long offset, } else { - // VR = "SQ" + /////////////////////// SeqEntry : VR = "SQ" + unsigned long l = newDocEntry->GetReadLength(); - if ( l != 0 ) // don't mess the delim_mode for zero-length sequence + if ( l != 0 ) // don't mess the delim_mode for 'zero-length sequence' { if ( l == 0xffffffff ) { - delim_mode = true; + delim_mode_intern = true; } else { - delim_mode = false; + delim_mode_intern = false; } } - - if ( (LoadMode & NO_SEQ) && ! delim_mode ) // User asked to skip SQ + + if ( (LoadMode & NO_SHADOWSEQ) && ! delim_mode_intern ) + { + // User asked to skip SeQuences *only* if they belong to Shadow Group + if ( newDocEntry->GetGroup()%2 != 0 ) + { + Fp->seekg( l, std::ios::cur); + used = false; + continue; + } + } + if ( (LoadMode & NO_SEQ) && ! delim_mode_intern ) { + // User asked to skip *any* SeQuence Fp->seekg( l, std::ios::cur); used = false; continue; - } + } + // delay the dynamic cast as late as possible + newSeqEntry = dynamic_cast(newDocEntry); - // no other way to create it ... - newSeqEntry->SetDelimitorMode( delim_mode ); + // no other way to create the Delimitor ... + newSeqEntry->SetDelimitorMode( delim_mode_intern ); // At the top of the hierarchy, stands a Document. When "set" // is a Document, then we are building the first depth level. @@ -1010,35 +1066,40 @@ void Document::ParseDES(DocEntrySet *set, long offset, // But when "set" is already a SQItem, we are building a nested // sequence, and hence the depth level of the new SeqEntry // we are building, is one level deeper: + + // time waste hunting if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) { newSeqEntry->SetDepthLevel( parentSQItem->GetDepthLevel() + 1 ); - newSeqEntry->SetKey( parentSQItem->GetBaseTagKey() - + newSeqEntry->GetKey() ); + + // newSeqEntry->SetKey( parentSQItem->GetBaseTagKey() + // + newSeqEntry->GetKey() ); } if ( l != 0 ) { // Don't try to parse zero-length sequences ParseSQ( newSeqEntry, newDocEntry->GetOffset(), - l, delim_mode); + l, delim_mode_intern); } - if( !set->AddEntry( newSeqEntry ) ) + if ( !set->AddEntry( newSeqEntry ) ) { + gdcmWarningMacro( "in ParseDES : cannot add a SeqEntry " + << newSeqEntry->GetKey() ); used = false; } - + if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) { - if( !used ) + if ( !used ) delete newDocEntry; break; } - } + } // end SeqEntry : VR = "SQ" - if( !used ) + if ( !used ) delete newDocEntry; - } + } // end While } /** @@ -1060,9 +1121,10 @@ void Document::ParseSQ( SeqEntry *seqEntry, if ( !newDocEntry ) { // FIXME Should warn user + gdcmWarningMacro("in ParseSQ : should never get here!"); break; } - if( delim_mode ) + if ( delim_mode ) { if ( newDocEntry->IsSequenceDelimitor() ) { @@ -1077,12 +1139,14 @@ void Document::ParseSQ( SeqEntry *seqEntry, } // create the current SQItem SQItem *itemSQ = new SQItem( seqEntry->GetDepthLevel() ); +/* std::ostringstream newBase; newBase << seqEntry->GetKey() << "/" << SQItemNumber << "#"; itemSQ->SetBaseTagKey( newBase.str() ); +*/ unsigned int l = newDocEntry->GetReadLength(); if ( l == 0xffffffff ) @@ -1099,7 +1163,9 @@ void Document::ParseSQ( SeqEntry *seqEntry, 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 ----------------- @@ -1129,7 +1195,7 @@ void Document::LoadDocEntry(DocEntry *entry) // (fffe e000) tells us an Element is beginning // (fffe e00d) tells us an Element just ended // (fffe e0dd) tells us the current SeQuence just ended - if( group == 0xfffe ) + if ( group == 0xfffe ) { // NO more value field for SQ ! return; @@ -1143,7 +1209,7 @@ void Document::LoadDocEntry(DocEntry *entry) } // The elements whose length is bigger than the specified upper bound - // are not loaded. Instead we leave a short notice of the offset of + // are not loaded. Instead we leave a short notice on the offset of // the element content and it's length. std::ostringstream s; @@ -1243,7 +1309,7 @@ void Document::LoadDocEntry(DocEntry *entry) str[length] = '\0'; //this is only useful when length is odd // Special DicomString call to properly handle \0 and even length std::string newValue; - if( length % 2 ) + if ( length % 2 ) { newValue = Util::DicomString(str, length+1); gdcmWarningMacro("Warning: bad length: " << length << @@ -1271,7 +1337,7 @@ void Document::LoadDocEntry(DocEntry *entry) return; } - if( vr == "UI" ) + if ( vr == "UI" ) { // Because of correspondance with the VR dic valEntry->SetValue(newValue); @@ -1283,7 +1349,9 @@ void Document::LoadDocEntry(DocEntry *entry) } else { - gdcmErrorMacro( "Should have a ValEntry, here !"); + gdcmWarningMacro("Should have a ValEntry, here ! " << valEntry->GetKey() + << " lgt : " << valEntry->GetReadLength() + << " at " << std::hex << valEntry->GetOffset()); } } @@ -1449,7 +1517,7 @@ std::string Document::FindDocEntryVR() Fp->read (vr, (size_t)2); vr[2] = 0; - if( !CheckDocEntryVR(vr) ) + if ( !CheckDocEntryVR(vr) ) { Fp->seekg(positionOnEntry, std::ios::beg); return GDCM_UNKNOWN; @@ -1497,14 +1565,14 @@ std::string Document::GetDocEntryValue(DocEntry *entry) // Elements with Value Multiplicity > 1 // contain a set of short integers (not a single one) - if( vr == "US" || vr == "SS" ) + if ( vr == "US" || vr == "SS" ) { uint16_t newInt16; nbInt = length / 2; for (int i=0; i < nbInt; i++) { - if( i != 0 ) + if ( i != 0 ) { s << '\\'; } @@ -1520,14 +1588,14 @@ std::string Document::GetDocEntryValue(DocEntry *entry) // as usual for standard multivaluated filels // Elements with Value Multiplicity > 1 // contain a set of integers (not a single one) - else if( vr == "UL" || vr == "SL" ) + else if ( vr == "UL" || vr == "SL" ) { uint32_t newInt32; nbInt = length / 4; for (int i=0; i < nbInt; i++) { - if( i != 0) + if ( i != 0) { s << '\\'; } @@ -1684,12 +1752,12 @@ void Document::FixDocEntryFoundLength(DocEntry *entry, //////// We encountered a 'delimiter' element i.e. a tag of the form // "fffe|xxxx" which is just a marker. Delimiters length should not be // taken into account. - else if( gr == 0xfffe ) + else if ( gr == 0xfffe ) { // According to the norm, fffe|0000 shouldn't exist. BUT the Philips // image gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm happens to // causes extra troubles... - if( entry->GetElement() != 0x0000 ) + if ( entry->GetElement() != 0x0000 ) { foundLength = 0; } @@ -1752,12 +1820,7 @@ bool Document::IsDocEntryAnInteger(DocEntry *entry) * true when we hope ours assuptions are OK */ bool Document::CheckSwap() -{ - // The only guaranted way of finding the swap code is to find a - // group tag since we know it's length has to be of four bytes i.e. - // 0x00000004. Finding the swap code in then straigthforward. Trouble - // occurs when we can't find such group... - +{ uint32_t s32; uint16_t s16; @@ -1772,7 +1835,7 @@ bool Document::CheckSwap() Fp->read(deb, 256); char *entCur = deb + 128; - if( memcmp(entCur, "DICM", (size_t)4) == 0 ) + if ( memcmp(entCur, "DICM", (size_t)4) == 0 ) { gdcmWarningMacro( "Looks like DICOM Version3 (preamble + DCM)" ); @@ -1796,11 +1859,11 @@ bool Document::CheckSwap() // even if elem 0002,0010 (Transfer Syntax) tells us the file is // *Implicit* VR (see former 'gdcmData/icone.dcm') - if( memcmp(entCur, "UL", (size_t)2) == 0 || - memcmp(entCur, "OB", (size_t)2) == 0 || - memcmp(entCur, "UI", (size_t)2) == 0 || - memcmp(entCur, "CS", (size_t)2) == 0 ) // CS, to remove later - // when Write DCM *adds* + if ( memcmp(entCur, "UL", (size_t)2) == 0 || + memcmp(entCur, "OB", (size_t)2) == 0 || + memcmp(entCur, "UI", (size_t)2) == 0 || + memcmp(entCur, "CS", (size_t)2) == 0 ) // CS, to remove later + // when Write DCM *adds* // FIXME // Use Document::dicom_vr to test all the possibilities // instead of just checking for UL, OB and UI !? group 0000 @@ -1862,12 +1925,12 @@ bool Document::CheckSwap() if ( SwapCode != 0 ) { - if( memcmp(entCur, "UL", (size_t)2) == 0 || - memcmp(entCur, "OB", (size_t)2) == 0 || - memcmp(entCur, "UI", (size_t)2) == 0 || - memcmp(entCur, "SH", (size_t)2) == 0 || - memcmp(entCur, "AE", (size_t)2) == 0 || - memcmp(entCur, "OB", (size_t)2) == 0 ) + if ( memcmp(entCur, "UL", (size_t)2) == 0 || + memcmp(entCur, "OB", (size_t)2) == 0 || + memcmp(entCur, "UI", (size_t)2) == 0 || + memcmp(entCur, "SH", (size_t)2) == 0 || + memcmp(entCur, "AE", (size_t)2) == 0 || + memcmp(entCur, "OB", (size_t)2) == 0 ) { Filetype = ExplicitVR; gdcmWarningMacro( "Group 0002 : Explicit Value Representation"); @@ -1959,7 +2022,8 @@ bool Document::CheckSwap() */ void Document::SwitchByteSwapCode() { - gdcmWarningMacro( "Switching Byte Swap code from "<< SwapCode); + gdcmWarningMacro( "Switching Byte Swap code from "<< SwapCode + << " at :" <tellg() ); if ( SwapCode == 1234 ) { SwapCode = 4321; @@ -1997,11 +2061,11 @@ void Document::SetMaxSizeLoadEntry(long newSize) } /** - * \brief Read the next tag but WITHOUT loading it's value + * \brief Read the next tag WITHOUT loading it's value * (read the 'Group Number', the 'Element Number', * gets the Dict Entry * gets the VR, gets the length, gets the offset value) - * @return On succes the newly created DocEntry, NULL on failure. + * @return On succes : the newly created DocEntry, NULL on failure. */ DocEntry *Document::ReadNextDocEntry() { @@ -2030,37 +2094,38 @@ DocEntry *Document::ReadNextDocEntry() std::string vr = FindDocEntryVR(); std::string realVR = vr; - if( vr == GDCM_UNKNOWN) + if ( vr == GDCM_UNKNOWN ) { if ( elem == 0x0000 ) // Group Length realVR = "UL"; // must be UL else { DictEntry *dictEntry = GetDictEntry(group,elem); - if( dictEntry ) + if ( dictEntry ) realVR = dictEntry->GetVR(); } } DocEntry *newEntry; - if( Global::GetVR()->IsVROfSequence(realVR) ) + if ( Global::GetVR()->IsVROfSequence(realVR) ) newEntry = NewSeqEntry(group, elem); - else if( Global::GetVR()->IsVROfStringRepresentable(realVR) ) + else if ( Global::GetVR()->IsVROfStringRepresentable(realVR) ) newEntry = NewValEntry(group, elem,vr); else newEntry = NewBinEntry(group, elem,vr); - if( vr == GDCM_UNKNOWN ) + if ( vr == GDCM_UNKNOWN ) { - if( Filetype == ExplicitVR ) + if ( Filetype == ExplicitVR ) { // We thought this was explicit VR, but we end up with an // implicit VR tag. Let's backtrack. if ( newEntry->GetGroup() != 0xfffe ) { std::string msg; - msg = Util::Format("Entry (%04x,%04x) should be Explicit VR\n", - newEntry->GetGroup(), newEntry->GetElement()); + int offset = Fp->tellg(); + msg = Util::Format("Entry (%04x,%04x) at 0x(%x) should be Explicit VR\n", + newEntry->GetGroup(), newEntry->GetElement(), offset ); gdcmWarningMacro( msg.c_str() ); } } @@ -2085,8 +2150,8 @@ DocEntry *Document::ReadNextDocEntry() /** * \brief Handle broken private tag from Philips NTSCAN - * where the endianess is being switch to BigEndian for no - * apparent reason + * where the endianess is being switched to BigEndian + * for no apparent reason * @return no return */ void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem)