X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=34b18e5f2d2dd451484efdeb672e8b431275d18e;hb=507c357466602345e4bd9de6c475e0887cf2ba36;hp=732a972384f2780941d95ae9f524c255a8b4f26d;hpb=47b54ba405f7bb1b1ce93f1db544d751b8eacc10;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 732a9723..34b18e5f 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/10/27 09:55:00 $ - Version: $Revision: 1.313 $ + Date: $Date: 2005/12/14 10:00:28 $ + Version: $Revision: 1.334 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -76,7 +76,6 @@ Document::~Document () //----------------------------------------------------------------------------- // Public - /** * \brief Loader. use SetLoadMode(), SetFileName() before ! * @return false if file cannot be open or no swap info was found, @@ -90,17 +89,6 @@ bool Document::Load( ) return false; } return DoTheLoadingDocumentJob( ); -} -/** - * \brief Loader. (DEPRECATED : not to break the API) - * @param fileName 'Document' (File or DicomDir) to be open for parsing - * @return false if file cannot be open or no swap info was found, - * or no tag was found. - */ -bool Document::Load( std::string const &fileName ) -{ - Filename = fileName; - return DoTheLoadingDocumentJob( ); } /** @@ -187,7 +175,7 @@ bool Document::DoTheLoadingDocumentJob( ) /// 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 + /// correct value, one needs to decide of the semantics by deciding /// whether the following tags are either : /// - multivaluated US, and hence loaded as ValEntry, but afterwards /// also used as BinEntry, which requires the proper conversion, @@ -338,22 +326,33 @@ bool Document::SetShaDict(DictKey const &dictName) * @return false when we're 150 % sure it's NOT a Dicom/Acr file, * true otherwise. */ -bool Document::IsReadable() +bool Document::IsParsable() { if ( Filetype == Unknown ) { - gdcmErrorMacro( "Wrong filetype"); + gdcmWarningMacro( "Wrong filetype for " << GetFileName()); return false; } if ( IsEmpty() ) { - gdcmErrorMacro( "No tag in internal hash table."); + gdcmWarningMacro( "No tag in internal hash table."); return false; } return true; } +/** + * \brief This predicate tells us whether or not the current Document + * was properly parsed and contains at least *one* Dicom Element + * (and nothing more, sorry). + * @return false when we're 150 % sure it's NOT a Dicom/Acr file, + * true otherwise. + */ +bool Document::IsReadable() +{ + return IsParsable(); +} /** * \brief Predicate for dicom version 3 file. @@ -552,7 +551,6 @@ double Document::SwapDouble(double a) return a; } - // // -----------------File I/O --------------- /** @@ -601,7 +599,10 @@ std::ifstream *Document::OpenFile() return 0; } - //-- ACR or DICOM with no Preamble; may start with a Shadow Group -- + //-- Broken ACR or DICOM with no Preamble; may start with a Shadow Group -- + + // FIXME : We cannot be sure the preable is only zeroes.. + // (see ACUSON-24-YBR_FULL-RLE.dcm ) if ( zero == 0x0001 || zero == 0x0100 || zero == 0x0002 || zero == 0x0200 || zero == 0x0003 || zero == 0x0300 || zero == 0x0004 || zero == 0x0400 || @@ -609,7 +610,7 @@ std::ifstream *Document::OpenFile() zero == 0x0007 || zero == 0x0700 || zero == 0x0008 || zero == 0x0800 ) { std::string msg = Util::Format( - "ACR/DICOM starting at the beginning of the file:(%04x)\n", zero); + "ACR/DICOM starting by 0x(%04x) at the beginning of the file\n", zero); // FIXME : is it a Warning message, or a Debug message? gdcmWarningMacro( msg.c_str() ); return Fp; @@ -707,15 +708,15 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) DocEntry *docEntry = GetDocEntry(group, elem); if ( !docEntry ) { - gdcmWarningMacro(std::hex << group << "|" << elem - << "doesn't exist" ); + gdcmDebugMacro(std::hex << group << "|" << elem + << " doesn't exist" ); return; } DataEntry *dataEntry = dynamic_cast(docEntry); if ( !dataEntry ) { gdcmWarningMacro(std::hex << group << "|" << elem - << "is NOT a DataEntry"); + << " is NOT a DataEntry"); return; } LoadEntryBinArea(dataEntry); @@ -761,11 +762,17 @@ void Document::LoadEntryBinArea(DataEntry *entry) uint32_t i; unsigned short vrLgth = Global::GetVR()->GetAtomicElementLength(entry->GetVR()); - if( entry->GetVR() == "OW" ) - vrLgth = 1; + +// FIXME : trouble expected if we read an ... OW Entry (LUT, etc ..) +// if( entry->GetVR() == "OW" ) +// vrLgth = 1; switch(vrLgth) { + case 1: + { + break; + } case 2: { uint16_t *data16 = (uint16_t *)data; @@ -924,7 +931,6 @@ uint32_t Document::ReadInt32() /** * \brief skips bytes inside the source file - * \warning NOT end user intended method ! * @return */ void Document::SkipBytes(uint32_t nBytes) @@ -934,7 +940,7 @@ void Document::SkipBytes(uint32_t nBytes) } /** - * \brief Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader + * \brief Re-computes the length of the Dicom group 0002. */ int Document::ComputeGroup0002Length( ) { @@ -958,11 +964,6 @@ int Document::ComputeGroup0002Length( ) { vr = entry->GetVR(); - // FIXME : group 0x0002 is *always* Explicit VR! - // --> Except for Implicit VR Transfer Syntax (GE Private) !! - - //if ( filetype == ExplicitVR ) - //{ //if ( (vr == "OB")||(vr == "OW")||(vr == "UT")||(vr == "SQ")) // (no SQ, OW, UT in group 0x0002;) if ( vr == "OB" ) @@ -970,7 +971,7 @@ int Document::ComputeGroup0002Length( ) // explicit VR AND (OB, OW, SQ, UT) : 4 more bytes groupLength += 4; } - //} + groupLength += 2 + 2 + 4 + entry->GetLength(); } } @@ -982,11 +983,37 @@ int Document::ComputeGroup0002Length( ) return groupLength; } +/** + * \brief CallStartMethod + */ +void Document::CallStartMethod() +{ + Progress = 0.0f; + Abort = false; + CommandManager::ExecuteCommand(this,CMD_STARTPROGRESS); +} + +/** + * \brief CallProgressMethod + */ +void Document::CallProgressMethod() +{ + CommandManager::ExecuteCommand(this,CMD_PROGRESS); +} + +/** + * \brief CallEndMethod + */ +void Document::CallEndMethod() +{ + Progress = 1.0f; + CommandManager::ExecuteCommand(this,CMD_ENDPROGRESS); +} + //----------------------------------------------------------------------------- // Private /** * \brief Loads all the needed Dictionaries - * \warning NOT end user intended method ! */ void Document::Initialize() { @@ -1014,7 +1041,7 @@ void Document::ParseDES(DocEntrySet *set, long offset, bool delim_mode_intern = delim_mode; bool first = true; gdcmDebugMacro( "Enter in ParseDES, delim-mode " << delim_mode - << " at offset " << std::hex << offset ); + << " at offset " << std::hex << "0x(" << offset << ")" ); while (true) { if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) @@ -1061,8 +1088,8 @@ void Document::ParseDES(DocEntrySet *set, long offset, { gdcmDebugMacro( "in ParseDES : cannot add a DataEntry " << newDataEntry->GetKey() - << " (at offset : " - << newDataEntry->GetOffset() << " )" ); + << " (at offset : 0x(" + << newDataEntry->GetOffset() << ") )" ); used=false; } else @@ -1071,7 +1098,6 @@ void Document::ParseDES(DocEntrySet *set, long offset, // Load only if we can add (not a duplicate key) LoadDocEntry( newDataEntry ); } - if ( newDataEntry->GetElement() == 0x0000 ) // if on group length { if ( newDataEntry->GetGroup()%2 != 0 ) // if Shadow Group @@ -1079,8 +1105,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, if ( LoadMode & LD_NOSHADOW ) // if user asked to skip shad.gr { std::string strLgrGroup = newDataEntry->GetString(); + int lgrGroup; - if ( newDataEntry->IsUnfound() ) + //if ( newDataEntry->IsUnfound() ) /?!? JPR { lgrGroup = atoi(strLgrGroup.c_str()); Fp->seekg(lgrGroup, std::ios::cur); @@ -1169,8 +1196,8 @@ void Document::ParseDES(DocEntrySet *set, long offset, { // Don't try to parse zero-length sequences gdcmDebugMacro( "Entry in ParseSQ, delim " << delim_mode_intern - << " at offset " << std::hex - << newDocEntry->GetOffset() ); + << " at offset 0x(" << std::hex + << newDocEntry->GetOffset() << ")"); ParseSQ( newSeqEntry, newDocEntry->GetOffset(), @@ -1183,8 +1210,8 @@ void Document::ParseDES(DocEntrySet *set, long offset, { gdcmWarningMacro( "in ParseDES : cannot add a SeqEntry " << newSeqEntry->GetKey() - << " (at offset : " - << newSeqEntry->GetOffset() << " )" ); + << " (at offset : 0x(" + << newSeqEntry->GetOffset() << ") )" ); used = false; } else @@ -1295,8 +1322,8 @@ DocEntry *Document::Backtrack(DocEntry *docEntry) long offset = PreviousDocEntry->GetOffset(); gdcmDebugMacro( "Backtrack :" << std::hex << group - << "|" << elem - << " at offset " << offset ); + << "|" << elem + << " at offset 0x(" <seekg(positionOnEntry, std::ios::beg); return GDCM_VRUNKNOWN; } @@ -1567,7 +1596,6 @@ bool Document::CheckDocEntryVR(const VRKey &vr) /** * \brief Skip a given Header Entry - * \warning NOT end user intended method ! * @param entry entry to skip */ void Document::SkipDocEntry(DocEntry *entry) @@ -1577,7 +1605,6 @@ void Document::SkipDocEntry(DocEntry *entry) /** * \brief Skips to the beginning of the next Header Entry - * \warning NOT end user intended method ! * @param currentDocEntry entry to skip */ void Document::SkipToNextDocEntry(DocEntry *currentDocEntry) @@ -1785,12 +1812,12 @@ bool Document::CheckSwap() if ( net2host ) { SwapCode = 4321; - gdcmDebugMacro( "HostByteOrder != NetworkByteOrder"); + gdcmDebugMacro( "HostByteOrder != NetworkByteOrder, SwapCode = 4321"); } else { SwapCode = 1234; - gdcmDebugMacro( "HostByteOrder = NetworkByteOrder"); + gdcmDebugMacro( "HostByteOrder = NetworkByteOrder, SwapCode = 1234"); } // Position the file position indicator at first tag @@ -1974,13 +2001,10 @@ void Document::SetMaxSizeLoadEntry(long newSize) */ DocEntry *Document::ReadNextDocEntry() { - uint16_t group; - uint16_t elem; - try { - group = ReadInt16(); - elem = ReadInt16(); + CurrentGroup = ReadInt16(); + CurrentElem = ReadInt16(); } catch ( FormatError ) { @@ -1990,11 +2014,11 @@ DocEntry *Document::ReadNextDocEntry() } // Sometimes file contains groups of tags with reversed endianess. - HandleBrokenEndian(group, elem); + HandleBrokenEndian(CurrentGroup, CurrentElem); // In 'true DICOM' files Group 0002 is always little endian if ( HasDCMPreamble ) - HandleOutOfGroup0002(group, elem); + HandleOutOfGroup0002(CurrentGroup, CurrentElem); VRKey vr = FindDocEntryVR(); @@ -2002,11 +2026,12 @@ DocEntry *Document::ReadNextDocEntry() if ( vr == GDCM_VRUNKNOWN ) { - if ( elem == 0x0000 ) // Group Length + if ( CurrentElem == 0x0000 ) // Group Length { realVR = "UL"; // must be UL } - else if (group%2 == 1 && (elem >= 0x0010 && elem <=0x00ff )) + else if (CurrentGroup%2 == 1 && + (CurrentElem >= 0x0010 && CurrentElem <=0x00ff )) { // DICOM PS 3-5 7.8.1 a) states that those // (gggg-0010->00FF where gggg is odd) attributes have to be LO @@ -2014,7 +2039,7 @@ DocEntry *Document::ReadNextDocEntry() } else { - DictEntry *dictEntry = GetDictEntry(group,elem); + DictEntry *dictEntry = GetDictEntry(CurrentGroup,CurrentElem); if ( dictEntry ) { realVR = dictEntry->GetVR(); @@ -2026,10 +2051,10 @@ DocEntry *Document::ReadNextDocEntry() DocEntry *newEntry; if ( Global::GetVR()->IsVROfSequence(realVR) ) - newEntry = NewSeqEntry(group, elem); + newEntry = NewSeqEntry(CurrentGroup, CurrentElem); else { - newEntry = NewDataEntry(group, elem, realVR); + newEntry = NewDataEntry(CurrentGroup, CurrentElem, realVR); static_cast(newEntry)->SetState(DataEntry::STATE_NOTLOADED); } @@ -2083,6 +2108,7 @@ void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem) if ((group == 0xfeff) && (elem == 0x00e0)) { // start endian swap mark for group found + gdcmDebugMacro( "Start endian swap mark found." ); reversedEndian++; SwitchByteSwapCode(); // fix the tag @@ -2092,6 +2118,7 @@ void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem) else if (group == 0xfffe && elem == 0xe00d && reversedEndian) { // end of reversed endian group + gdcmDebugMacro( "End of reversed endian." ); reversedEndian--; SwitchByteSwapCode(); } @@ -2126,12 +2153,18 @@ void Document::HandleOutOfGroup0002(uint16_t &group, uint16_t &elem) { Group0002Parsed = true; // we just came out of group 0002 - // if Transfer syntax is Big Endian we have to change CheckSwap + // if Transfer Syntax is Big Endian we have to change CheckSwap std::string ts = GetTransferSyntax(); + if ( ts == GDCM_UNKNOWN ) + { + gdcmDebugMacro("True DICOM File, with NO Transfer Syntax (?!) " ); + return; + } if ( !Global::GetTS()->IsTransferSyntax(ts) ) { - gdcmDebugMacro("True DICOM File, with NO Tansfer Syntax: " << ts ); + gdcmWarningMacro("True DICOM File, with illegal Transfer Syntax: [" + << ts << "]"); return; } @@ -2140,9 +2173,9 @@ void Document::HandleOutOfGroup0002(uint16_t &group, uint16_t &elem) if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian ) - { - Filetype = ImplicitVR; - } + { + Filetype = ImplicitVR; + } // FIXME Strangely, this works with //'Implicit VR BigEndian Transfer Syntax (GE Private)