From 906464b1c71b1b623f8202a693e75a358a5bd965 Mon Sep 17 00:00:00 2001 From: malaterre Date: Thu, 16 Feb 2006 20:06:13 +0000 Subject: [PATCH] ENH: Try to sync gdcm CVS and gdcm 1.2. ~2000 lines of changes, please be gentle if something breaks. --- src/gdcmDicomDir.cxx | 71 ++++- src/gdcmDicomDir.h | 6 +- src/gdcmDicomDirMeta.cxx | 6 +- src/gdcmDictEntry.cxx | 5 +- src/gdcmDirList.h | 6 +- src/gdcmDocEntry.cxx | 13 +- src/gdcmDocEntry.h | 6 +- src/gdcmDocEntrySet.cxx | 20 +- src/gdcmDocument.cxx | 51 ++-- src/gdcmDocument.h | 14 +- src/gdcmElementSet.cxx | 6 +- src/gdcmFile.cxx | 34 +-- src/gdcmFile.h | 11 +- src/gdcmFileHelper.cxx | 22 +- src/gdcmFileHelper.h | 6 +- src/gdcmOrientation.h | 7 +- src/gdcmPixelReadConvert.cxx | 25 +- src/gdcmPixelReadConvert.h | 10 +- src/gdcmPixelWriteConvert.h | 7 +- src/gdcmRLEFrame.h | 7 +- src/gdcmRLEFramesInfo.h | 5 +- src/gdcmSQItem.cxx | 6 +- src/gdcmSQItem.h | 6 +- src/gdcmSeqEntry.cxx | 6 +- src/gdcmSeqEntry.h | 8 +- src/gdcmSerieHelper.cxx | 489 ++++++++++++++++------------------- src/gdcmSerieHelper.h | 71 +++-- src/gdcmUtil.cxx | 39 ++- src/gdcmValidator.cxx | 10 +- 29 files changed, 508 insertions(+), 465 deletions(-) diff --git a/src/gdcmDicomDir.cxx b/src/gdcmDicomDir.cxx index a12b7fa7..2ca54af0 100644 --- a/src/gdcmDicomDir.cxx +++ b/src/gdcmDicomDir.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDir.cxx,v $ Language: C++ - Date: $Date: 2006/01/27 10:01:33 $ - Version: $Revision: 1.185 $ + Date: $Date: 2006/02/16 20:06:13 $ + Version: $Revision: 1.186 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -56,7 +56,7 @@ #if defined(__BORLANDC__) #include // for memset -#endif +#endif // ---------------------------------------------------------------------------- // Note for future developpers @@ -129,6 +129,36 @@ DicomDir::DicomDir() NewMeta(); } +#ifndef GDCM_LEGACY_REMOVE +/** + * \brief Constructor Parses recursively the directory and creates the DicomDir + * or uses an already built DICOMDIR, depending on 'parseDir' value. + * @param fileName name + * - of the root directory (parseDir = true) + * - of the DICOMDIR (parseDir = false) + * @param parseDir boolean + * - true if user passed an entry point + * and wants to explore recursively the directories + * - false if user passed an already built DICOMDIR file + * and wants to use it + * @deprecated use : new DicomDir() + [ SetLoadMode(lm) + ] SetDirectoryName(name) + * or : new DicomDir() + SetFileName(name) + */ +DicomDir::DicomDir(std::string const &fileName, bool parseDir ): + Document( ) +{ + // At this step, Document constructor is already executed, + // whatever user passed (either a root directory or a DICOMDIR) + // and whatever the value of parseDir was. + // (nothing is cheked in Document constructor, to avoid overhead) + + ParseDir = parseDir; + SetLoadMode (LD_ALL); // concerns only dicom files + SetFileName( fileName ); + Load( ); +} +#endif + /** * \brief Canonical destructor */ @@ -159,6 +189,28 @@ bool DicomDir::Load( ) } return DoTheLoadingJob( ); } +#ifndef GDCM_LEGACY_REMOVE +/** + * \brief Loader. (DEPRECATED : kept not to break the API) + * @param fileName file to be open for parsing + * @return false if file cannot be open or no swap info was found, + * or no tag was found. + * @deprecated use SetFileName(n) + Load() instead + */ +bool DicomDir::Load(std::string const &fileName ) +{ + // We should clean out anything that already exists. + Initialize(); // sets all private fields to NULL + + SetFileName( fileName ); + if (!ParseDir) + { + if ( ! this->Document::Load( ) ) + return false; + } + return DoTheLoadingJob( ); +} +#endif /** * \brief Does the Loading Job (internal use only) @@ -208,11 +260,11 @@ bool DicomDir::DoTheLoadingJob( ) const char *cwd = getcwd(buf, 2048); if( cwd ) { - SetFileName( buf ); // will be converted into a string + SetFileName( buf ); // will be converted into a string } else { - gdcmErrorMacro( "Path was too long to fit on 2048 bytes" ); + gdcmErrorMacro( "Path was too long to fit on 2048 bytes" ); } } NewMeta(); @@ -893,9 +945,9 @@ void DicomDir::SetElement(std::string const &path, DicomDirType type, default: return; } - + // FIXME : troubles found when it's a SeqEntry - + // removed all the seems-to-be-useless stuff about Referenced Image Sequence // to avoid further troubles // imageElem 0008 1140 "" // Referenced Image Sequence @@ -919,8 +971,7 @@ void DicomDir::SetElement(std::string const &path, DicomDirType type, { // NULL when we Build Up (ex nihilo) a DICOMDIR // or when we add the META elems - - val = header->GetEntryString(tmpGr, tmpEl); + val = header->GetEntryString(tmpGr, tmpEl); } else { @@ -928,7 +979,7 @@ void DicomDir::SetElement(std::string const &path, DicomDirType type, } if ( val == GDCM_UNFOUND) - { + { if ( tmpGr == 0x0004 ) // never present in File ! { switch (tmpEl) diff --git a/src/gdcmDicomDir.h b/src/gdcmDicomDir.h index 11f379f9..869bac74 100644 --- a/src/gdcmDicomDir.h +++ b/src/gdcmDicomDir.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDir.h,v $ Language: C++ - Date: $Date: 2005/11/29 17:21:34 $ - Version: $Revision: 1.73 $ + Date: $Date: 2006/02/16 20:06:13 $ + 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 @@ -56,6 +56,7 @@ public: /// \brief Constructs a DicomDir with a RefCounter static DicomDir *New() {return new DicomDir();} + GDCM_LEGACY( bool Load(std::string const &filename) ); bool Load( ); void Print(std::ostream &os = std::cout, std::string const &indent = "" ); @@ -114,6 +115,7 @@ public: protected: DicomDir(); + GDCM_LEGACY( DicomDir(std::string const &filename, bool parseDir = false) ); ~DicomDir(); void CreateDicomDirChainedList(std::string const &path); diff --git a/src/gdcmDicomDirMeta.cxx b/src/gdcmDicomDirMeta.cxx index 0d450d0b..dae4d4e3 100644 --- a/src/gdcmDicomDirMeta.cxx +++ b/src/gdcmDicomDirMeta.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDirMeta.cxx,v $ Language: C++ - Date: $Date: 2005/11/04 15:33:35 $ - Version: $Revision: 1.34 $ + Date: $Date: 2006/02/16 20:06:13 $ + Version: $Revision: 1.35 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -56,7 +56,7 @@ DicomDirMeta::~DicomDirMeta() * @return */ void DicomDirMeta::WriteContent(std::ofstream *fp, FileType filetype) -{ +{ // 'File Meta Information Version' uint8_t fmiv[2] = {0x02,0x00}; diff --git a/src/gdcmDictEntry.cxx b/src/gdcmDictEntry.cxx index 958a4f51..b348b39e 100644 --- a/src/gdcmDictEntry.cxx +++ b/src/gdcmDictEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDictEntry.cxx,v $ Language: C++ - Date: $Date: 2005/11/30 08:48:17 $ - Version: $Revision: 1.59 $ + Date: $Date: 2006/02/16 20:06:13 $ + Version: $Revision: 1.60 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -40,7 +40,6 @@ DictEntry::DictEntry(uint16_t group, uint16_t elem, VRKey const &vr, TagName const &vm, TagName const &name) - { Tag.SetGroup(group); Tag.SetElement(elem); diff --git a/src/gdcmDirList.h b/src/gdcmDirList.h index bd848459..e907f49a 100644 --- a/src/gdcmDirList.h +++ b/src/gdcmDirList.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDirList.h,v $ Language: C++ - Date: $Date: 2005/11/28 17:24:21 $ - Version: $Revision: 1.30 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.31 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -37,7 +37,7 @@ typedef std::vector DirListType; /** * \brief List containing the file headers of all the 'gdcm readable' files - * found by exploring (possibely recursively) a root directory. + * found by exploring (possibly recursively) a root directory. */ class GDCM_EXPORT DirList : public Base { diff --git a/src/gdcmDocEntry.cxx b/src/gdcmDocEntry.cxx index 4b91fc35..535e3bc9 100644 --- a/src/gdcmDocEntry.cxx +++ b/src/gdcmDocEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntry.cxx,v $ Language: C++ - Date: $Date: 2005/12/21 14:52:12 $ - Version: $Revision: 1.80 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.81 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -71,9 +71,9 @@ void DocEntry::WriteContent(std::ofstream *fp, FileType filetype) { uint32_t ffff = 0xffffffff; uint16_t group = GetGroup(); - + ///\todo allow skipping Shadow groups - + VRKey vr = GetVR(); uint16_t elem = GetElement(); uint32_t lgth = GetLength(); @@ -85,7 +85,7 @@ void DocEntry::WriteContent(std::ofstream *fp, FileType filetype) // we just *always* ignore spurious fffe|0000 tag ! return; } - + // // ----------- Writes the common part // @@ -101,10 +101,9 @@ void DocEntry::WriteContent(std::ofstream *fp, FileType filetype) // Dicom V3 group 0x0002 is *always* Explicit VR ! if ( filetype == ExplicitVR || filetype == JPEG || group == 0x0002 ) { - // ----------- Writes the common part : the VR + the length - // Special case of delimiters: + // Special case of delimiters: if (group == 0xfffe) { // Delimiters have NO Value Representation diff --git a/src/gdcmDocEntry.h b/src/gdcmDocEntry.h index ee5c7eb6..dc09c90a 100644 --- a/src/gdcmDocEntry.h +++ b/src/gdcmDocEntry.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntry.h,v $ Language: C++ - Date: $Date: 2005/11/29 12:48:46 $ - Version: $Revision: 1.59 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.60 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -65,7 +65,7 @@ public: /// Dictionnary, of the current Dicom entry VRKey const &GetVR() const { return DicomDict->GetVR(); } - /// \brief Returns the 'Value Multiplicity' (e.g. "1", 6", "1-n", "3-n"), + /// \brief Returns the 'Value Multiplicity' (e.g. "1", "6", "1-n", "3-n"), /// found in the Dicom entry or in the Dicom Dictionnary /// of the current Dicom entry std::string const &GetVM() const { return DicomDict->GetVM(); } diff --git a/src/gdcmDocEntrySet.cxx b/src/gdcmDocEntrySet.cxx index 7ba938fb..18e713d8 100644 --- a/src/gdcmDocEntrySet.cxx +++ b/src/gdcmDocEntrySet.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntrySet.cxx,v $ Language: C++ - Date: $Date: 2006/01/27 10:01:33 $ - Version: $Revision: 1.69 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.70 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -121,7 +121,7 @@ SeqEntry *DocEntrySet::GetSeqEntry(uint16_t group, uint16_t elem) DocEntry *currentEntry = GetDocEntry(group, elem); if ( !currentEntry ) return NULL; - + return dynamic_cast(currentEntry); } @@ -214,8 +214,8 @@ bool DocEntrySet::SetEntryBinArea(uint8_t *content, int lgth, DataEntry *entry) * failed). */ DataEntry *DocEntrySet::InsertEntryString(std::string const &value, - uint16_t group, uint16_t elem, - VRKey const &vr ) + uint16_t group, uint16_t elem, + VRKey const &vr ) { DataEntry *dataEntry = 0; DocEntry *currentEntry = GetDocEntry( group, elem ); @@ -272,8 +272,8 @@ DataEntry *DocEntrySet::InsertEntryString(std::string const &value, * failed). */ DataEntry *DocEntrySet::InsertEntryBinArea(uint8_t *binArea, int lgth, - uint16_t group, uint16_t elem, - VRKey const &vr ) + uint16_t group, uint16_t elem, + VRKey const &vr ) { DataEntry *dataEntry = 0; DocEntry *currentEntry = GetDocEntry( group, elem ); @@ -492,14 +492,14 @@ DictEntry *DocEntrySet::GetDictEntry(uint16_t group, uint16_t elem, DictEntry *goodEntry = dictEntry; VRKey goodVR = vr; TagName vm; - if (elem == 0x0000) + if (elem == 0x0000) goodVR="UL"; if ( goodEntry ) { if ( goodVR != goodEntry->GetVR() && goodVR != GDCM_VRUNKNOWN ) - { + { gdcmWarningMacro("For (" << std::hex << group << "|" << elem << "), found VR : [" << vr << "]" << " expected: [" << goodEntry->GetVR() << "]" ) ; @@ -520,7 +520,7 @@ DictEntry *DocEntrySet::GetDictEntry(uint16_t group, uint16_t elem, if (dictEntry) { - goodEntry = DictEntry::New(group, elem, goodVR, vm,//"FIXME", + goodEntry = DictEntry::New(group, elem, goodVR, vm, dictEntry->GetName() ); } else diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 3803b0a7..0ce0c26b 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2006/02/09 10:48:04 $ - Version: $Revision: 1.341 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.342 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -95,6 +95,20 @@ bool Document::Load( ) return DoTheLoadingDocumentJob( ); } +#ifndef GDCM_LEGACY_REMOVE +/** + * \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( ); +} +#endif + /** * \brief Performs the Loading Job (internal use only) * @return false if file cannot be open or no swap info was found, @@ -118,7 +132,7 @@ bool Document::DoTheLoadingDocumentJob( ) Group0002Parsed = false; gdcmDebugMacro( "Starting parsing of file: " << Filename.c_str()); - + // Computes the total length of the file Fp->seekg(0, std::ios::end); // Once per Document ! long lgt = Fp->tellg(); // Once per Document ! @@ -640,7 +654,7 @@ std::ifstream *Document::OpenFile() // -- Neither ACR/No Preamble Dicom nor DICOMV3 file CloseFile(); - // Don't user Warning nor Error, not to polute the output + // Don't user Warning nor Error, not to pollute the output // while directory recursive parsing ... gdcmDebugMacro( "Neither ACR/No Preamble Dicom nor DICOMV3 file: " << Filename.c_str()); @@ -969,7 +983,6 @@ int Document::ComputeGroup0002Length( ) // explicit VR AND (OB, OW, SQ, UT) : 4 more bytes groupLength += 4; } - groupLength += 2 + 2 + 4 + entry->GetLength(); } } @@ -1012,6 +1025,7 @@ void Document::CallEndMethod() // Private /** * \brief Loads all the needed Dictionaries + * \warning NOT end user intended method ! */ void Document::Initialize() { @@ -1066,9 +1080,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, // but we didn't get it (private Sequence + Implicit VR) // we have to backtrack. if ( !first && newDocEntry->IsItemStarter() ) - { - // Debug message within the method ! - newDocEntry = Backtrack(newDocEntry); + { + // Debug message within the method ! + newDocEntry = Backtrack(newDocEntry); } else { @@ -1344,8 +1358,7 @@ DocEntry *Document::Backtrack(DocEntry *docEntry) newEntry->SetOffset(offset); // Move back to the beginning of the Sequence - // Fp->seekg( 0, std::ios::beg); // JPRx - // Fp->seekg(offset, std::ios::cur); // JPRx + Fp->seekg(offset, std::ios::beg); // Only for Shadow Implicit VR SQ return newEntry; } @@ -1369,7 +1382,6 @@ void Document::LoadDocEntry(DocEntry *entry, bool forceLoad) // (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 - // // (fffe 0000) is an 'impossible' tag value, // found in MR-PHILIPS-16-Multi-Seq.dcm @@ -1437,7 +1449,7 @@ void Document::FindDocEntryLength( DocEntry *entry ) // The following reserved two bytes (see PS 3.5-2003, section // "7.1.2 Data element structure with explicit vr", p 27) must be // skipped before proceeding on reading the length on 4 bytes. - + Fp->seekg( 2L, std::ios::cur); // Once per OW,OB,SQ DocEntry uint32_t length32 = ReadInt32(); @@ -1500,7 +1512,7 @@ void Document::FindDocEntryLength( DocEntry *entry ) // Well ... group 0002 is always coded in 'Explicit VR Litle Endian' // even if Transfer Syntax is 'Implicit VR ...' // --> Except for 'Implicit VR Big Endian Transfer Syntax GE Private' - + FixDocEntryFoundLength( entry, ReadInt32() ); return; } @@ -1508,6 +1520,7 @@ void Document::FindDocEntryLength( DocEntry *entry ) /** * \brief Find the Length till the next sequence delimiter + * \warning NOT end user intended method ! * @return */ uint32_t Document::FindDocEntryLengthOBOrOW() @@ -1515,7 +1528,7 @@ uint32_t Document::FindDocEntryLengthOBOrOW() { // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data. long positionOnEntry = Fp->tellg(); // Only for OB,OW DataElements - + bool foundSequenceDelimiter = false; uint32_t totalLength = 0; @@ -1537,11 +1550,9 @@ uint32_t Document::FindDocEntryLengthOBOrOW() totalLength += 4; if ( group != 0xfffe || ( ( elem != 0xe0dd ) && ( elem != 0xe000 ) ) ) { - // long filePosition = Fp->tellg(); JPRx gdcmWarningMacro( "Neither an Item tag nor a Sequence delimiter tag on :" << std::hex << group << " , " << elem - //<< ") -before- position x(" << filePosition // JPRx << ")" ); Fp->seekg(positionOnEntry, std::ios::beg); // Once per fragment (if any) of OB,OW DataElements @@ -1863,8 +1874,6 @@ bool Document::CheckSwap() // Position the file position indicator at first tag // (i.e. after the file preamble and the "DICM" string). - //Fp->seekg(0, std::ios::beg); // JPRx - Fp->seekg ( 132L, std::ios::beg); // Once per Document return true; } // ------------------------------- End of DicomV3 ---------------- @@ -2055,7 +2064,7 @@ DocEntry *Document::ReadNextDocEntry() } // In 'true DICOM' files Group 0002 is always little endian - if ( HasDCMPreamble ) + if ( HasDCMPreamble ) { if ( !Group0002Parsed && CurrentGroup != 0x0002) // avoid calling a function when useless HandleOutOfGroup0002(CurrentGroup, CurrentElem); @@ -2096,7 +2105,7 @@ DocEntry *Document::ReadNextDocEntry() } } } - + DocEntry *newEntry; //if ( Global::GetVR()->IsVROfSequence(realVR) ) if (realVR == "SQ") @@ -2233,7 +2242,7 @@ void Document::HandleOutOfGroup0002(uint16_t &group, uint16_t &elem) group = SwapShort(group); elem = SwapShort(elem); } - + /// \todo find a trick to warn user and stop processing if ( s == TS::DeflatedExplicitVRLittleEndian) diff --git a/src/gdcmDocument.h b/src/gdcmDocument.h index 9dbd9af1..841bd685 100644 --- a/src/gdcmDocument.h +++ b/src/gdcmDocument.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.h,v $ Language: C++ - Date: $Date: 2006/02/09 10:48:05 $ - Version: $Revision: 1.139 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.140 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -48,8 +48,9 @@ public: // Loading //Deprecated : use SetFileName() + Load() - //GDCM_LEGACY( virtual bool Load( std::string const &filename ) ); - //virtual bool Load( std::string const &filename ); +#ifndef GDCM_LEGACY_REMOVE + virtual bool Load( std::string const &filename ); +#endif virtual bool Load( ); // Dictionaries @@ -88,7 +89,7 @@ public: virtual void LoadEntryBinArea(uint16_t group, uint16_t elem); virtual void LoadEntryBinArea(DataEntry *entry); - //void LoadDocEntrySafe(DocEntry *entry); + void SetMaxSizeLoadEntry(long); void AddForceLoadElement(uint16_t group, uint16_t elem); // Ordering of Documents @@ -184,7 +185,7 @@ protected: private: // Methods void Initialize(); - bool DoTheLoadingDocumentJob(); + bool DoTheLoadingDocumentJob(); // System access (meaning endian related !?) uint16_t SwapShort(uint16_t); @@ -215,7 +216,6 @@ private: bool CheckSwap(); void SwitchByteSwapCode(); - void SetMaxSizeLoadEntry(long); // DocEntry related utilities DocEntry *ReadNextDocEntry(); diff --git a/src/gdcmElementSet.cxx b/src/gdcmElementSet.cxx index f073783c..e7855bdd 100644 --- a/src/gdcmElementSet.cxx +++ b/src/gdcmElementSet.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmElementSet.cxx,v $ Language: C++ - Date: $Date: 2006/01/31 11:39:47 $ - Version: $Revision: 1.72 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.73 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -268,7 +268,7 @@ void ElementSet::Print(std::ostream &os, std::string const & ) entry->SetPrintLevel(PrintLevel); entry->Print(os); - if ( dynamic_cast(entry) ) + if ( dynamic_cast(entry) ) { // Avoid the newline for a sequence: continue; diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index c7b50b50..e2effd63 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2006/02/07 12:37:19 $ - Version: $Revision: 1.314 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.315 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -124,7 +124,7 @@ File::File(): /** * \brief Canonical destructor. */ -File::~File () +File::~File() { if ( RLEInfo ) delete RLEInfo; @@ -568,7 +568,6 @@ float File::GetYSpacing() * XOrigin, YOrigin, ZOrigin (of the top left image corner) * of 2 consecutive images, and the Orientation * Computing ZSpacing on a single image is not really meaningfull ! - * @return Z dimension of a voxel-to be */ float File::GetZSpacing() @@ -781,6 +780,8 @@ bool File::GetImageOrientationPatient( float iop[6] ) { std::string strImOriPat; //iop is supposed to be float[6] + iop[0] = iop[4] = 1.; + iop[1] = iop[2] = iop[3] = iop[5] = 0.; // 0020 0037 DS REL Image Orientation (Patient) if ( (strImOriPat = GetEntryString(0x0020,0x0037)) != GDCM_UNFOUND ) @@ -788,14 +789,11 @@ bool File::GetImageOrientationPatient( float iop[6] ) if ( sscanf( strImOriPat.c_str(), "%f \\ %f \\%f \\%f \\%f \\%f ", &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 ) { - iop[0] = iop[4] = 1.; - iop[1] = iop[2] = iop[3] = iop[5] = 0.; gdcmWarningMacro( "Wrong Image Orientation Patient (0020,0037)." << " Less than 6 values were found." ); return false; } - else - return true; + return true; } //For ACR-NEMA // 0020 0035 DS REL Image Orientation (RET) @@ -804,14 +802,11 @@ bool File::GetImageOrientationPatient( float iop[6] ) if ( sscanf( strImOriPat.c_str(), "%f \\ %f \\%f \\%f \\%f \\%f ", &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 ) { - iop[0] = iop[4] = 1.; - iop[1] = iop[2] = iop[3] = iop[5] = 0.; gdcmWarningMacro( "wrong Image Orientation Patient (0020,0035). " << "Less than 6 values were found." ); return false; } - else - return true; + return true; } return false; } @@ -1180,7 +1175,7 @@ float File::GetRescaleIntercept() /** *\brief gets the info from 0028,1053 : Rescale Slope - * @return Rescale Slope. defaulted to 0.0 is not found or empty + * @return Rescale Slope. defaulted to 1.0 is not found or empty */ float File::GetRescaleSlope() { @@ -1526,7 +1521,6 @@ bool File::Write(std::string fileName, FileType writetype) return true; } - //----------------------------------------------------------------------------- // Protected @@ -1666,7 +1660,7 @@ void File::ComputeJPEGFragmentInfo() long fragmentLength; int i=0; uint32_t sum = 0; - while ( (fragmentLength = ReadTagLength(0xfffe, 0xe000)) != 0 ) + while ( (fragmentLength = ReadTagLength(0xfffe, 0xe000)) != 0 ) { // Since we have read the basic offset table, let's check the value were correct // or else produce a warning: @@ -1746,7 +1740,7 @@ bool File::ReadTag(uint16_t testGroup, uint16_t testElem) return false; } if ( itemTagGroup != testGroup || itemTagElem != testElem ) - { + { // in order not to pollute output we don't warn on 'delimitors' if (itemTagGroup != 0xfffe || testGroup != 0xfffe ) gdcmWarningMacro( "Wrong Item Tag found:" @@ -1843,15 +1837,14 @@ void File::ReadEncapsulatedBasicOffsetTable() // These are the deprecated method that one day should be removed (after the next release) -//#ifndef GDCM_LEGACY_REMOVE +#ifndef GDCM_LEGACY_REMOVE /* * \ brief Loader. (DEPRECATED : temporaryly kept not to break the API) * @ param fileName file to be open for parsing * @ return false if file cannot be open or no swap info was found, * or no tag was found. - * @ deprecated Use the Load() [ + SetLoadMode() ] + SetFileName() functions instead + * @deprecated Use the Load() [ + SetLoadMode() ] + SetFileName() functions instead */ - /* bool File::Load( std::string const &fileName ) { GDCM_LEGACY_REPLACED_BODY(File::Load(std::string), "1.2", @@ -1862,8 +1855,7 @@ bool File::Load( std::string const &fileName ) return DoTheLoadingJob( ); } -*/ -//#endif +#endif //----------------------------------------------------------------------------- // Print diff --git a/src/gdcmFile.h b/src/gdcmFile.h index d58bc54e..6e191429 100644 --- a/src/gdcmFile.h +++ b/src/gdcmFile.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.h,v $ Language: C++ - Date: $Date: 2005/12/21 14:52:13 $ - Version: $Revision: 1.123 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.124 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -104,7 +104,7 @@ public: static File *New() {return new File();} // Loading - //GDCM_LEGACY(bool Load( std::string const &filename )); + GDCM_LEGACY(bool Load( std::string const &filename )); bool Load(); // Standard values and informations contained in the header bool IsReadable(); @@ -171,13 +171,12 @@ public: void AnonymizeNoLoad(); /// Replace patient's own information by info from the Anonymization list bool AnonymizeFile(); - + bool Write(std::string fileName, FileType filetype); - protected: File(); - ~File(); + virtual ~File(); /// \brief Protect the Writer from writing illegal groups bool MayIWrite(uint16_t group) { if (group < 8 && group !=2 ) return false; else return true; } diff --git a/src/gdcmFileHelper.cxx b/src/gdcmFileHelper.cxx index 433a2d50..62cc53dc 100644 --- a/src/gdcmFileHelper.cxx +++ b/src/gdcmFileHelper.cxx @@ -4,8 +4,8 @@ Module: $RCSfile: gdcmFileHelper.cxx,v $ Language: C++ - Date: $Date: 2006/02/15 21:58:54 $ - Version: $Revision: 1.92 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.93 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -381,7 +381,7 @@ uint8_t *FileHelper::GetImageData() * - DOES NOT transform Grey plane + 3 Palettes into a RGB Plane * @return Pointer to newly allocated pixel data. * (uint8_t is just for prototyping. feel free to cast) - * NULL if alloc fails + * NULL if alloc fails */ uint8_t *FileHelper::GetImageDataRaw () { @@ -390,7 +390,7 @@ uint8_t *FileHelper::GetImageDataRaw () #ifndef GDCM_LEGACY_REMOVE /* - * \ brief Useless function, since PixelReadConverter forces us + * \brief Useless function, since PixelReadConverter forces us * copy the Pixels anyway. * Reads the pixels from disk (uncompress if necessary), * Transforms YBR pixels, if any, into RGB pixels @@ -398,7 +398,7 @@ uint8_t *FileHelper::GetImageDataRaw () * Transforms single Grey plane + 3 Palettes into a RGB Plane * Copies at most MaxSize bytes of pixel data to caller allocated * memory space. - * \ warning This function allows people that want to build a volume + * \warning This function allows people that want to build a volume * from an image stack *not to* have, first to get the image pixels, * and then move them to the volume area. * It's absolutely useless for any VTK user since vtk chooses @@ -407,12 +407,12 @@ uint8_t *FileHelper::GetImageDataRaw () * to load the image line by line, starting from the end. * VTK users have to call GetImageData * - * @ param destination Address (in caller's memory space) at which the + * @param destination Address (in caller's memory space) at which the * pixel data should be copied - * @ param maxSize Maximum number of bytes to be copied. When MaxSize + * @param maxSize Maximum number of bytes to be copied. When MaxSize * is not sufficient to hold the pixel data the copy is not * executed (i.e. no partial copy). - * @ return On success, the number of bytes actually copied. Zero on + * @return On success, the number of bytes actually copied. Zero on * failure e.g. MaxSize is lower than necessary. */ size_t FileHelper::GetImageDataIntoVector (void *destination, size_t maxSize) @@ -684,7 +684,6 @@ bool FileHelper::Write(std::string const &fileName) break; case JPEG: SetWriteFileTypeToJPEG(); - std::cerr << "Writting as JPEG" << std::endl; break; } CheckMandatoryElements(); @@ -1000,7 +999,7 @@ void FileHelper::SetWriteFileTypeToACR() } /** - * \brief Sets in the File the TransferSyntax to 'Explicit VR Little Endian" + * \brief Sets in the File the TransferSyntax to 'JPEG' */ void FileHelper::SetWriteFileTypeToJPEG() { @@ -1014,6 +1013,9 @@ void FileHelper::SetWriteFileTypeToJPEG() tss->Delete(); } +/** + * \brief Sets in the File the TransferSyntax to 'Explicit VR Little Endian" + */ void FileHelper::SetWriteFileTypeToExplicitVR() { std::string ts = Util::DicomString( diff --git a/src/gdcmFileHelper.h b/src/gdcmFileHelper.h index 0bfd57ec..5a64bdfc 100644 --- a/src/gdcmFileHelper.h +++ b/src/gdcmFileHelper.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFileHelper.h,v $ Language: C++ - Date: $Date: 2005/11/30 13:42:19 $ - Version: $Revision: 1.37 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.38 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -220,7 +220,7 @@ private: // Write variables /// \brief (WMODE_RAW, WMODE_RGB) FileMode WriteMode; - + /// \brief (ImplicitVR, ExplicitVR, ACR, ACR_LIBIDO) FileType WriteType; diff --git a/src/gdcmOrientation.h b/src/gdcmOrientation.h index 1ff24325..0692d9d5 100644 --- a/src/gdcmOrientation.h +++ b/src/gdcmOrientation.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmOrientation.h,v $ Language: C++ - Date: $Date: 2005/11/28 16:31:23 $ - Version: $Revision: 1.17 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.18 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -20,7 +20,6 @@ #define GDCMORIENTATION_H #include "gdcmRefCounter.h" - #include namespace gdcm @@ -107,7 +106,7 @@ public: std::string GetOrientation ( File *file ); static const char* GetOrientationTypeString(OrientationType const o); - + protected: /// \brief Constructor Orientation() {} diff --git a/src/gdcmPixelReadConvert.cxx b/src/gdcmPixelReadConvert.cxx index f5003106..343534fa 100644 --- a/src/gdcmPixelReadConvert.cxx +++ b/src/gdcmPixelReadConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.cxx,v $ Language: C++ - Date: $Date: 2006/01/27 10:01:34 $ - Version: $Revision: 1.109 $ + Date: $Date: 2006/02/16 20:06:14 $ + Version: $Revision: 1.110 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -86,7 +86,7 @@ bool PixelReadConvert::IsRawRGB() * \brief Gets various usefull informations from the file header * @param file gdcm::File pointer */ -void PixelReadConvert::GrabInformationsFromFile( File *file, +void PixelReadConvert::GrabInformationsFromFile( File *file, FileHelper *fileHelper ) { // Number of Bits Allocated for storing a Pixel is defaulted to 16 @@ -119,12 +119,12 @@ void PixelReadConvert::GrabInformationsFromFile( File *file, //PixelSize = file->GetPixelSize(); Useless PixelSign = file->IsSignedPixelData(); SwapCode = file->GetSwapCode(); - + IsPrivateGETransferSyntax = IsMPEG = IsJPEG2000 = IsJPEGLS = IsJPEGLossy = IsJPEGLossless = IsRLELossless = false; - + if (! file->IsDicomV3() ) // Should be ACR-NEMA file { IsRaw = true; @@ -289,7 +289,7 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) if ( PixelDataLength != RawSize ) { gdcmWarningMacro( "Mismatch between PixelReadConvert : " - << PixelDataLength << " and RawSize : " << RawSize ); + << PixelDataLength << " and RawSize : " << RawSize ); } //todo : is it the right patch? @@ -317,15 +317,6 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) if (remainingLength !=0 ) fp->read( raw, remainingLength); - //if ( PixelDataLength > RawSize ) - //{ - // fp->read( (char*)Raw, RawSize); // Read all the frames with a single fread - //} - //else - //{ - // fp->read( (char*)Raw, PixelDataLength); // Read all the frames with a single fread - //} - if ( fp->fail() || fp->eof()) { gdcmWarningMacro( "Reading of Raw pixel data failed." ); @@ -607,7 +598,7 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) * and * - (0028,1101),(0028,1102),(0028,1102) * xxx Palette Color Lookup Table Descriptor are found - * and + * and * - (0028,1201),(0028,1202),(0028,1202) * xxx Palette Color Lookup Table Data - are found * \warning does NOT deal with : @@ -844,7 +835,7 @@ void PixelReadConvert::BuildLUTRGBA() void PixelReadConvert::ConvertSwapZone() { unsigned int i; - + // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax', // then the header is in little endian format and the pixel data is in // big endian format. When reading the header, GDCM has already established diff --git a/src/gdcmPixelReadConvert.h b/src/gdcmPixelReadConvert.h index 3305788b..368b0248 100644 --- a/src/gdcmPixelReadConvert.h +++ b/src/gdcmPixelReadConvert.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.h,v $ Language: C++ - Date: $Date: 2005/11/29 17:21:35 $ - Version: $Revision: 1.28 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.29 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -38,7 +38,7 @@ typedef void (*VOID_FUNCTION_PUINT8_PFILE_POINTER)(uint8_t *, File *); /** * \brief Utility container for gathering the various forms the pixel data * migth take during the user demanded processes. - * WARNING : *none* of these functions may be invoked by gdm user + * WARNING : *none* of these functions may be invoked by gdcm user * (internal use only) */ class GDCM_EXPORT PixelReadConvert : public Base @@ -137,11 +137,11 @@ private: //int PixelSize; // useless bool PixelSign; int SwapCode; - + // cache whether this is a strange GE transfer syntax (which has // one transfer syntax for the header and another for the pixel data). bool IsPrivateGETransferSyntax; - + bool IsRaw; bool IsJPEG2000; bool IsJPEGLS; diff --git a/src/gdcmPixelWriteConvert.h b/src/gdcmPixelWriteConvert.h index bbdcad27..01c20c2a 100644 --- a/src/gdcmPixelWriteConvert.h +++ b/src/gdcmPixelWriteConvert.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelWriteConvert.h,v $ Language: C++ - Date: $Date: 2005/10/23 15:09:19 $ - Version: $Revision: 1.7 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.8 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -40,13 +40,13 @@ private: virtual ~PixelWriteConvert(); // Set/Get of images and their size - void SetReadData(uint8_t *data, size_t size); /// \brief returns ReadData uint8_t *GetReadData() { return ReadData; } /// \brief returns ReadDataSize size_t GetReadDataSize() { return ReadDataSize; } + /// \brief Set UserData void SetUserData(uint8_t *data, size_t size); /// \brief returns UserData uint8_t *GetUserData() { return UserData; } @@ -57,7 +57,6 @@ private: uint8_t *GetData(); size_t GetDataSize(); - // Variables /// Pixel data represented as RGB after LUT color interpretation. uint8_t *ReadData; diff --git a/src/gdcmRLEFrame.h b/src/gdcmRLEFrame.h index b667116b..f265b713 100644 --- a/src/gdcmRLEFrame.h +++ b/src/gdcmRLEFrame.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmRLEFrame.h,v $ Language: C++ - Date: $Date: 2005/11/28 17:24:21 $ - Version: $Revision: 1.19 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.20 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -43,7 +43,7 @@ namespace gdcm * - the offsets of each segment of the frame, * - the (corresponding) lengths of each segment of the frame. */ - class GDCM_EXPORT RLEFrame : public Base +class GDCM_EXPORT RLEFrame : public Base { friend class File; friend class RLEFramesInfo; @@ -64,7 +64,6 @@ private: bool ReadAndDecompressRLEFragment( uint8_t *subRaw, long fragmentSize, long rawSegmentSize, std::ifstream *fp ); -//private: unsigned int NumberOfFragments; long Offset[15]; long Length[15]; diff --git a/src/gdcmRLEFramesInfo.h b/src/gdcmRLEFramesInfo.h index 56724c2e..c4f44ddb 100644 --- a/src/gdcmRLEFramesInfo.h +++ b/src/gdcmRLEFramesInfo.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmRLEFramesInfo.h,v $ Language: C++ - Date: $Date: 2005/11/18 14:33:24 $ - Version: $Revision: 1.20 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.21 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -58,7 +58,6 @@ private: RLEFrame *GetFirstFrame(); RLEFrame *GetNextFrame(); -//private:: typedef std::list RLEFrameList; RLEFrameList Frames; diff --git a/src/gdcmSQItem.cxx b/src/gdcmSQItem.cxx index 9f26de3b..f4f2a766 100644 --- a/src/gdcmSQItem.cxx +++ b/src/gdcmSQItem.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSQItem.cxx,v $ Language: C++ - Date: $Date: 2005/12/13 09:22:05 $ - Version: $Revision: 1.83 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.84 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -95,7 +95,7 @@ void SQItem::WriteContent(std::ofstream *fp, FileType filetype) // because we wrote the Item as a 'no Length' item for(j=0;j<4;++j) { - binary_write( *fp, itemt[j]); // fffe e000 0000 0000 + binary_write( *fp, itemt[j]); // fffe e000 0000 0000 } } diff --git a/src/gdcmSQItem.h b/src/gdcmSQItem.h index cd6c7ccc..8d4e81c7 100644 --- a/src/gdcmSQItem.h +++ b/src/gdcmSQItem.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSQItem.h,v $ Language: C++ - Date: $Date: 2005/11/29 17:11:52 $ - Version: $Revision: 1.50 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.51 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -46,7 +46,7 @@ public: static SQItem *New(int depthLevel) {return new SQItem(depthLevel);} virtual void Print(std::ostream &os = std::cout, - std::string const &indent = "" ); + std::string const &indent = "" ); void WriteContent(std::ofstream *fp, FileType filetype); uint32_t ComputeFullLength(); diff --git a/src/gdcmSeqEntry.cxx b/src/gdcmSeqEntry.cxx index 43cad17b..5e7113f6 100644 --- a/src/gdcmSeqEntry.cxx +++ b/src/gdcmSeqEntry.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSeqEntry.cxx,v $ Language: C++ - Date: $Date: 2005/12/01 09:12:21 $ - Version: $Revision: 1.64 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.65 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -86,7 +86,7 @@ void SeqEntry::WriteContent(std::ofstream *fp, FileType filetype) // ignore 'Zero length' Sequences if ( GetReadLength() == 0 ) return; - + DocEntry::WriteContent(fp, filetype); for(ListSQItem::iterator cc = Items.begin(); cc != Items.end(); diff --git a/src/gdcmSeqEntry.h b/src/gdcmSeqEntry.h index e26eddd0..3e9c8c83 100644 --- a/src/gdcmSeqEntry.h +++ b/src/gdcmSeqEntry.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSeqEntry.h,v $ Language: C++ - Date: $Date: 2005/11/29 12:48:47 $ - Version: $Revision: 1.39 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.40 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -50,7 +50,7 @@ public: void Print(std::ostream &os = std::cout, std::string const &indent = "" ); void WriteContent(std::ofstream *fp, FileType filetype); uint32_t ComputeFullLength(); - + void AddSQItem(SQItem *it, int itemNumber); void ClearSQItem(); SQItem *GetFirstSQItem(); @@ -60,7 +60,9 @@ public: /// Sets the delimitor mode void SetDelimitorMode(bool dm) { DelimitorMode = dm; } + /// Sets the Sequence Delimitation Item void SetDelimitationItem(DocEntry *e); + /// Gets the Sequence Delimitation Item DocEntry *GetDelimitationItem() { return SeqTerm;} diff --git a/src/gdcmSerieHelper.cxx b/src/gdcmSerieHelper.cxx index 5d7b6c48..81358a14 100644 --- a/src/gdcmSerieHelper.cxx +++ b/src/gdcmSerieHelper.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSerieHelper.cxx,v $ Language: C++ - Date: $Date: 2006/02/05 23:13:36 $ - Version: $Revision: 1.46 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.47 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -25,13 +25,12 @@ #include #include -#include #include +#include #include //for sscanf -namespace gdcm +namespace gdcm { -//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Constructor / Destructor @@ -75,6 +74,8 @@ void SerieHelper::ClearAll() delete l; // remove the container l = GetNextSingleSerieUIDFileSet(); } + // Need to clear that too: + SingleSerieUIDFileSetHT.clear(); } //----------------------------------------------------------------------------- @@ -96,48 +97,7 @@ void SerieHelper::AddFileName(std::string const &filename) if ( header->IsReadable() ) { - int allrules = 1; - // First step : the user defined a set of rules for the DICOM file - // he is looking for. - // Make sure the file corresponds to his set of rules: - - std::string s; - for(SerieExRestrictions::iterator it2 = ExRestrictions.begin(); - it2 != ExRestrictions.end(); - ++it2) - { - const ExRule &r = *it2; - s = header->GetEntryString( r.group, r.elem ); - if ( !Util::CompareDicomString(s, r.value.c_str(), r.op) ) - { - // Argh ! This rule is unmatched; let's just quit - - allrules = 0; - break; - } - } - - if ( allrules ) // all rules are respected: - { - // Allright! we have a found a DICOM that matches the user expectation. - // Let's add it! - - // 0020 000e UI REL Series Instance UID - const std::string &uid = header->GetEntryString(0x0020, 0x000e); - // if uid == GDCM_UNFOUND then consistently we should find GDCM_UNFOUND - // no need here to do anything special - - - if ( SingleSerieUIDFileSetHT.count(uid) == 0 ) - { - gdcmDebugMacro(" New Serie UID :[" << uid << "]"); - // create a std::list in 'uid' position - SingleSerieUIDFileSetHT[uid] = new FileList; - } - // Current Serie UID and DICOM header seems to match; add the file: - SingleSerieUIDFileSetHT[uid]->push_back( header ); - } - else + if ( !AddFile( header ) ) { // at least one rule was unmatched we need to deallocate the file: header->Delete(); @@ -167,45 +127,55 @@ void SerieHelper::AddFileName(std::string const &filename) * *no* coherence check is performed, but those specified * by SerieHelper::AddRestriction() * @param header gdcm::File* of the file to deal with + * @return true if file was added, false if file was rejected */ -void SerieHelper::AddGdcmFile(File *header) +bool SerieHelper::AddFile(File *header) { - int allrules = 1; - // First step the user has defined a set of rules for the DICOM - // he is looking for. - // make sure the file correspond to his set of rules: - for(SerieRestrictions::iterator it = Restrictions.begin(); - it != Restrictions.end(); - ++it) + int allrules = 1; + // First step the user has defined a set of rules for the DICOM + // he is looking for. + // make sure the file correspond to his set of rules: + + std::string s; + for(SerieExRestrictions::iterator it2 = ExRestrictions.begin(); + it2 != ExRestrictions.end(); + ++it2) + { + const ExRule &r = *it2; + s = header->GetEntryString( r.group, r.elem ); + if ( !Util::CompareDicomString(s, r.value.c_str(), r.op) ) { - const Rule &r = *it; - const std::string s;// = header->GetEntryString( r.first ); - if ( !Util::DicomStringEqual(s, r.second.c_str()) ) - { - // Argh ! This rule is unmatch let's just quit - allrules = 0; - break; - } + // Argh ! This rule is unmatched; let's just quit + allrules = 0; + break; } - if ( allrules ) // all rules are respected: - { - // Allright ! we have a found a DICOM that match the user expectation. - // Let's add it ! - - const std::string &uid = "0"; - // Serie UID of the gdcm::File* may be different. - // User is supposed to know what he wants + } - if ( SingleSerieUIDFileSetHT.count(uid) == 0 ) - { - gdcmDebugMacro(" New Serie UID :[" << uid << "]"); - // create a std::list in 'uid' position - SingleSerieUIDFileSetHT[uid] = new FileList; - } - // Current Serie UID and DICOM header seems to match; add the file: - SingleSerieUIDFileSetHT[uid]->push_back( header ); + if ( allrules ) // all rules are respected: + { + // Allright! we have a found a DICOM that matches the user expectation. + // Let's add it to the specific 'id' which by default is uid (Serie UID) + // but can be `refined` by user with more paramater (see AddRestriction(g,e)) + + std::string id = CreateUniqueSeriesIdentifier( header ); + // if id == GDCM_UNFOUND then consistently we should find GDCM_UNFOUND + // no need here to do anything special + + if ( SingleSerieUIDFileSetHT.count(id) == 0 ) + { + gdcmDebugMacro(" New Serie UID :[" << id << "]"); + // create a std::list in 'id' position + SingleSerieUIDFileSetHT[id] = new FileList; } - // Even if a rule was unmatch we don't deallocate the gdcm::File: + // Current Serie UID and DICOM header seems to match add the file: + SingleSerieUIDFileSetHT[id]->push_back( header ); + } + else + { + // one rule not matched, tell user: + return false; + } + return true; } /** @@ -231,29 +201,35 @@ void SerieHelper::AddRestriction(TagKey const &key, ExRestrictions.push_back( r ); } +void SerieHelper::AddRestriction(TagKey const &key) +{ + ExRule r; + r.group = key[0]; + r.elem = key[1]; + ExRefine.push_back( r ); +} + +#ifndef GDCM_LEGACY_REMOVE /** * \brief add a rule for restricting a DICOM file to be in the serie we are - * trying to find. For example you can select only the DICOM file from a + * trying to find. For example you can select only the DICOM files from a * directory which would have a particular EchoTime==4.0. * This method is a user level, value is not required to be formatted as a DICOM * string - * \todo find a trick to allow user if he wants the Rectrictions to be *ored* - * (and not only *anded*) * @param group tag group number we want restrict on a given value * @param elem tag element number we want restrict on a given value * @param value value to be checked to exclude File * @param op operator we want to use to check + * @deprecated use : AddRestriction(TagKey const &key, + * std::string const &value, int op); */ void SerieHelper::AddRestriction(uint16_t group, uint16_t elem, std::string const &value, int op) { - ExRule r; - r.group = group; - r.elem = elem; - r.value = value; - r.op = op; - ExRestrictions.push_back( r ); + TagKey t(group, elem); + AddRestriction(t, value, op); } +#endif /** * \brief add an extra 'SerieDetail' for building a 'Serie Identifier' @@ -346,13 +322,17 @@ bool SerieHelper::IsCoherent(FileList *fileSet) return false; if ( (*it)->IsSignedPixelData() != signedPixelData ) return false; - // probabely more is to be checked (?) + // probabely more is to be checked (?) } return true; } #ifndef GDCM_LEGACY_REMOVE - +/** + * \brief accessor (DEPRECATED : use GetFirstSingleSerieUIDFileSet ) + * Warning : 'coherent' means here they have the same Serie UID + * @return The first FileList if found, otherwhise NULL + */ FileList *SerieHelper::GetFirstCoherentFileList() { ItFileSetHt = SingleSerieUIDFileSetHT.begin(); @@ -361,7 +341,12 @@ FileList *SerieHelper::GetFirstCoherentFileList() return NULL; } - +/** + * \brief accessor (DEPRECATED : use GetNextSingleSerieUIDFileSet ) + * Warning : 'coherent' means here they have the same Serie UID + * \note : meaningfull only if GetFirstCoherentFileList() already called + * @return The next FileList if found, otherwhise NULL + */ FileList *SerieHelper::GetNextCoherentFileList() { gdcmAssertMacro (ItFileSetHt != SingleSerieUIDFileSetHT.end()); @@ -372,7 +357,12 @@ FileList *SerieHelper::GetNextCoherentFileList() return NULL; } - +/** + * \brief accessor (DEPRECATED : use GetSingleSerieUIDFileSet ) + * Warning : 'coherent' means here they have the same Serie UID + * @param SerieUID SerieUID + * \return pointer to the FileList if found, otherwhise NULL + */ FileList *SerieHelper::GetCoherentFileList(std::string SerieUID) { if ( SingleSerieUIDFileSetHT.count(SerieUID) == 0 ) @@ -435,9 +425,9 @@ XCoherentFileSetmap SerieHelper::SplitOnOrientation(FileList *fileSet) if (nb == 0 ) return CoherentFileSet; float iop[6]; - std::string strOrient; - std::ostringstream ossOrient; + std::ostringstream ossOrient; + FileList::const_iterator it = fileSet->begin(); it ++; for ( ; @@ -459,8 +449,6 @@ XCoherentFileSetmap SerieHelper::SplitOnOrientation(FileList *fileSet) } strOrient = ossOrient.str(); ossOrient.str(""); - // FIXME : is it a 'cleaner' way to initialize an ostringstream? - if ( CoherentFileSet.count(strOrient) == 0 ) { gdcmDebugMacro(" New Orientation :[" << strOrient << "]"); @@ -469,7 +457,7 @@ XCoherentFileSetmap SerieHelper::SplitOnOrientation(FileList *fileSet) } // Current Orientation and DICOM header match; add the file: CoherentFileSet[strOrient]->push_back( (*it) ); - } + } return CoherentFileSet; } @@ -533,7 +521,7 @@ XCoherentFileSetmap SerieHelper::SplitOnPosition(FileList *fileSet) } strPosition = ossPosition.str(); ossPosition.str(""); - + if ( CoherentFileSet.count(strPosition) == 0 ) { gdcmDebugMacro(" New Position :[" << strPosition << "]"); @@ -556,7 +544,7 @@ XCoherentFileSetmap SerieHelper::SplitOnPosition(FileList *fileSet) */ XCoherentFileSetmap SerieHelper::SplitOnTagValue(FileList *fileSet, - uint16_t group, uint16_t elem) + uint16_t group, uint16_t element) { XCoherentFileSetmap CoherentFileSet; @@ -576,7 +564,7 @@ XCoherentFileSetmap SerieHelper::SplitOnTagValue(FileList *fileSet, // 0020,0032 : Image Position Patient // 0020,0030 : Image Position (RET) - strTagValue = (*it)->GetEntryString(group,elem); + strTagValue = (*it)->GetEntryString(group,element); if ( CoherentFileSet.count(strTagValue) == 0 ) { @@ -656,7 +644,7 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) ipp[0] = (*it)->GetXOrigin(); ipp[1] = (*it)->GetYOrigin(); ipp[2] = (*it)->GetZOrigin(); - + dist = 0; for ( int i = 0; i < 3; ++i ) { @@ -668,7 +656,6 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) min = (min < dist) ? min : dist; max = (max > dist) ? max : dist; } - } // Find out if min/max are coherent @@ -680,33 +667,34 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) } // Check to see if image shares a common position - bool ok = true; - for (std::multimap::iterator it2 = distmultimap.begin(); - it2 != distmultimap.end(); - ++it2) - { - if (distmultimap.count((*it2).first) != 1) - { - gdcmErrorMacro("File: " - << ((*it2).second->GetFileName()) - << " Distance: " - << (*it2).first - << " position is not unique"); - ok = false; - } - } - if (!ok) - { - return false; - } - + bool ok = true; + for (std::multimap::iterator it2 = distmultimap.begin(); + it2 != distmultimap.end(); + ++it2) + { + if (distmultimap.count((*it2).first) != 1) + { + gdcmErrorMacro("File: " + << ((*it2).second->GetFileName()) + << " Distance: " + << (*it2).first + << " position is not unique"); + + ok = false; + } + } + if (!ok) + { + return false; + } + fileList->clear(); // doesn't delete list elements, only nodes if (DirectOrder) { for (std::multimap::iterator it3 = distmultimap.begin(); - it3 != distmultimap.end(); - ++it3) + it3 != distmultimap.end(); + ++it3) { fileList->push_back( (*it3).second ); } @@ -720,7 +708,7 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) it4--; fileList->push_back( (*it4).second ); } while (it4 != distmultimap.begin() ); - } + } distmultimap.clear(); @@ -742,7 +730,7 @@ bool SerieHelper::ImageNumberGreaterThan(File *file1, File *file2) * \note Works only on bona fide files (i.e image number is a character string * corresponding to an integer) * within a bona fide serie (i.e image numbers are consecutive) - * @param fileList File set (same Serie UID) to sort + * @param fileList File set (same Serie UID) to sort * @return false if non bona fide stuff encountered */ bool SerieHelper::ImageNumberOrdering(FileList *fileList) @@ -767,14 +755,10 @@ bool SerieHelper::ImageNumberOrdering(FileList *fileList) << " No ImageNumberOrdering sort performed."); return false; } - if (DirectOrder) - Sort(fileList,SerieHelper::ImageNumberLessThan); -// std::sort(fileList->begin(), fileList->end(), -// SerieHelper::ImageNumberLessThan ); + if (DirectOrder) + Sort(fileList,SerieHelper::ImageNumberLessThan); else - Sort(fileList,SerieHelper::ImageNumberGreaterThan); -// std::sort(fileList->begin(), fileList->end(), -// SerieHelper::ImageNumberGreaterThan ); + Sort(fileList,SerieHelper::ImageNumberGreaterThan); return true; } @@ -796,13 +780,9 @@ bool SerieHelper::FileNameGreaterThan(File *file1, File *file2) bool SerieHelper::FileNameOrdering(FileList *fileList) { if (DirectOrder) - Sort(fileList,SerieHelper::FileNameLessThan); -// std::sort(fileList->begin(), fileList->end(), -// SerieHelper::FileNameLessThan); + Sort(fileList,SerieHelper::FileNameLessThan); else - Sort(fileList,SerieHelper::FileNameGreaterThan); -// std::sort(fileList->begin(), fileList->end(), -// SerieHelper::FileNameGreaterThan); + Sort(fileList,SerieHelper::FileNameGreaterThan); return true; } @@ -814,9 +794,7 @@ bool SerieHelper::FileNameOrdering(FileList *fileList) */ bool SerieHelper::UserOrdering(FileList *fileList) { - Sort(fileList,SerieHelper::UserLessThanFunction); -// std::sort(fileList->begin(), fileList->end(), -// SerieHelper::UserLessThanFunction); + Sort(fileList,SerieHelper::UserLessThanFunction); if (!DirectOrder) { std::reverse(fileList->begin(), fileList->end()); @@ -824,6 +802,64 @@ bool SerieHelper::UserOrdering(FileList *fileList) return true; } +//----------------------------------------------------------------------------- +// Print +/** + * \brief Canonical printer. + */ +void SerieHelper::Print(std::ostream &os, std::string const &indent) +{ + // For all the Coherent File lists of the gdcm::Serie + SingleSerieUIDFileSetmap::iterator itl = SingleSerieUIDFileSetHT.begin(); + if ( itl == SingleSerieUIDFileSetHT.end() ) + { + gdcmWarningMacro( "No SingleSerieUID File set found" ); + return; + } + while (itl != SingleSerieUIDFileSetHT.end()) + { + os << "Serie UID :[" << itl->first << "]" << std::endl; + + // For all the files of a SingleSerieUID File set + for (FileList::iterator it = (itl->second)->begin(); + it != (itl->second)->end(); + ++it) + { + os << indent << " --- " << (*it)->GetFileName() << std::endl; + } + ++itl; + } +} + +void SerieHelper::CreateDefaultUniqueSeriesIdentifier() +{ + // If the user requests, additional information can be appended + // to the SeriesUID to further differentiate volumes in the DICOM + // objects being processed. + + // 0020 0011 Series Number + // A scout scan prior to a CT volume scan can share the same + // SeriesUID, but they will sometimes have a different Series Number + AddRestriction( TagKey(0x0020, 0x0011) ); + // 0018 0024 Sequence Name + // For T1-map and phase-contrast MRA, the different flip angles and + // directions are only distinguished by the Sequence Name + AddRestriction( TagKey(0x0018, 0x0024) ); + // 0018 0050 Slice Thickness + // On some CT systems, scout scans and subsequence volume scans will + // have the same SeriesUID and Series Number - YET the slice + // thickness will differ from the scout slice and the volume slices. + AddRestriction( TagKey(0x0018, 0x0050)); + // 0028 0010 Rows + // If the 2D images in a sequence don't have the same number of rows, + // then it is difficult to reconstruct them into a 3D volume. + AddRestriction( TagKey(0x0028, 0x0010)); + // 0028 0011 Columns + // If the 2D images in a sequence don't have the same number of columns, + // then it is difficult to reconstruct them into a 3D volume. + AddRestriction( TagKey(0x0028, 0x0011)); +} + /** * \brief Heuristics to *try* to build a Serie Identifier that would ensure * all the images are coherent. @@ -841,110 +877,49 @@ std::string SerieHelper::CreateUniqueSeriesIdentifier( File *inFile ) { if( inFile->IsReadable() ) { - // 0020 000e UI REL Series Instance UID - std::string uid = inFile->GetEntryString (0x0020, 0x000e); + // 0020 000e UI REL Series Instance UID + std::string uid = inFile->GetEntryString (0x0020, 0x000e); std::string id = uid.c_str(); if(m_UseSeriesDetails) - { - // If the user requests, additional information can be appended - // to the SeriesUID to further differentiate volumes in the DICOM - // objects being processed. - - // 0020 0011 Series Number - // A scout scan prior to a CT volume scan can share the same - // SeriesUID, but they will sometimes have a different Series Number - std::string sNum = inFile->GetEntryString(0x0020, 0x0011); - if( sNum == gdcm::GDCM_UNFOUND ) - { - sNum = ""; - } - // 0018 0024 Sequence Name - // For T1-map and phase-contrast MRA, the different flip angles and - // directions are only distinguished by the Sequence Name - std::string sName = inFile->GetEntryString(0x0018, 0x0024); - if( sName == gdcm::GDCM_UNFOUND ) - { - sName = ""; - } - - // You can think on checking Image Orientation (0020,0037), as well. - - - // 0018 0050 Slice Thickness - // On some CT systems, scout scans and subsequence volume scans will - // have the same SeriesUID and Series Number - YET the slice - // thickness will differ from the scout slice and the volume slices. - std::string sThick = inFile->GetEntryString (0x0018, 0x0050); - if( sThick == gdcm::GDCM_UNFOUND ) - { - sThick = ""; - } - // 0028 0010 Rows - // If the 2D images in a sequence don't have the same number of rows, - // then it is difficult to reconstruct them into a 3D volume. - std::string sRows = inFile->GetEntryString (0x0028, 0x0010); - if( sRows == gdcm::GDCM_UNFOUND ) - { - sRows = ""; - } - // 0028 0011 Columns - // If the 2D images in a sequence don't have the same number of columns, - // then it is difficult to reconstruct them into a 3D volume. - std::string sColumns = inFile->GetEntryString (0x0028, 0x0011); - if( sColumns == gdcm::GDCM_UNFOUND ) - { - sColumns = ""; - } - - // Concat the new info - std::string num = sNum.c_str(); - num += sName.c_str(); - num += sThick.c_str(); - num += sRows.c_str(); - num += sColumns.c_str(); - - // Add a loop, here, to deal with any extra user supplied tag. - // We allow user to add his own critierions - // (he knows more than we do about his images!) - // ex : in tagging series, the only pertinent tag is - // 0018|1312 [In-plane Phase Encoding Direction] values : ROW/COLUMN - - std::string s; - for(SeriesExDetails::iterator it2 = ExDetails.begin(); - it2 != ExDetails.end(); - ++it2) { - const ExDetail &r = *it2; - s = inFile->GetEntryString( r.group, r.elem ); - num += s.c_str(); + for(SerieExRestrictions::iterator it2 = ExRefine.begin(); + it2 != ExRefine.end(); + ++it2) + { + const ExRule &r = *it2; + std::string s = inFile->GetEntryString( r.group, r.elem ); + if( s == gdcm::GDCM_UNFOUND ) + { + s = ""; + } + if( id == uid && !s.empty() ) + { + id += "."; // add separator + } + id += s; + } } - - // Append the new info to the SeriesUID - id += "."; - id += num.c_str(); - } - - // Eliminate non-alphanum characters, including whitespace... - // that may have been introduced by concats. - for(unsigned int i=0; i= 'a' && id[i] <= 'z') - || (id[i] >= '0' && id[i] <= '9') - || (id[i] >= 'A' && id[i] <= 'Z'))) - { - id.erase(i, 1); - } - } - return id; - } - else // Could not open inFile - { - gdcmWarningMacro("Could not parse series info."); - std::string id = gdcm::GDCM_UNFOUND; - return id; - } + // Eliminate non-alnum characters, including whitespace... + // that may have been introduced by concats. + for(unsigned int i=0; i= 'a' && id[i] <= 'z') + || (id[i] >= '0' && id[i] <= '9') + || (id[i] >= 'A' && id[i] <= 'Z'))) + { + id.erase(i, 1); + } + } + return id; + } + else // Could not open inFile + { + gdcmWarningMacro("Could not parse series info."); + std::string id = gdcm::GDCM_UNFOUND; + return id; + } } /** @@ -1005,34 +980,6 @@ std::string SerieHelper::CreateUserDefinedFileIdentifier( File * inFile ) return id; } -//----------------------------------------------------------------------------- -// Print -/** - * \brief Canonical printer. - */ -void SerieHelper::Print(std::ostream &os, std::string const &indent) -{ - // For all the Coherent File lists of the gdcm::Serie - SingleSerieUIDFileSetmap::iterator itl = SingleSerieUIDFileSetHT.begin(); - if ( itl == SingleSerieUIDFileSetHT.end() ) - { - gdcmWarningMacro( "No SingleSerieUID File set found" ); - return; - } - while (itl != SingleSerieUIDFileSetHT.end()) - { - os << "Serie UID :[" << itl->first << "]" << std::endl; - - // For all the files of a SingleSerieUID File set - for (FileList::iterator it = (itl->second)->begin(); - it != (itl->second)->end(); - ++it) - { - os << indent << " --- " << (*it)->GetFileName() << std::endl; - } - ++itl; - } -} //----------------------------------------------------------------------------- // Sort diff --git a/src/gdcmSerieHelper.h b/src/gdcmSerieHelper.h index 1b9a8ff8..d04d005e 100644 --- a/src/gdcmSerieHelper.h +++ b/src/gdcmSerieHelper.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSerieHelper.h,v $ Language: C++ - Date: $Date: 2006/01/18 15:25:07 $ - Version: $Revision: 1.36 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.37 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -32,13 +32,16 @@ namespace gdcm class File; typedef std::vector FileList; - - /// \brief XCoherent stands for 'Extra Coherent', +#ifndef GDCM_LEGACY_REMOVE +typedef std::vector GdcmFileList; +#endif + + /// \brief XCoherent stands for 'Extra Coherent', /// (The name 'Coherent' would be enough but it was used before; /// I don't want to put a bomb in the code) /// Any 'better name' is welcome ! - typedef std::map XCoherentFileSetmap; - + typedef std::map XCoherentFileSetmap; + typedef bool (*BOOL_FUNCTION_PFILE_PFILE_POINTER)(File *, File *); //----------------------------------------------------------------------------- @@ -75,12 +78,16 @@ public: /// \todo should return bool or throw error ? void AddFileName(std::string const &filename); - void AddGdcmFile(File *header); + bool AddFile(File *header); +#ifndef GDCM_LEGACY_REMOVE + bool AddGdcmFile(File* header) { return AddFile(header); } +#endif void SetDirectory(std::string const &dir, bool recursive=false); bool IsCoherent(FileList *fileSet); void OrderFileList(FileList *fileSet); - + void Clear() { ClearAll(); } + /// \brief Gets the FIRST Single SerieUID Fileset. /// Deprecated; kept not to break the API /// \note Caller must call OrderFileList first @@ -103,6 +110,7 @@ public: /// \todo : find a trick to allow user to say the retrictetons are ored /// (not only anded) /// ex : keep the images whose SerieNumber is 101 or 102 or 103. + void AddRestriction(TagKey const &key); void AddRestriction(TagKey const &key, std::string const &value, int op); void AddRestriction(uint16_t group, uint16_t elem, std::string const &value, int op); @@ -111,14 +119,31 @@ public: /// and SeriesName to identify when a single SeriesUID contains /// multiple 3D volumes - as can occur with perfusion and DTI imaging void SetUseSeriesDetails( bool useSeriesDetails ) - { m_UseSeriesDetails = useSeriesDetails;} - bool GetUseSeriesDetails( ){ return m_UseSeriesDetails; } - + { + m_UseSeriesDetails = useSeriesDetails; + } + bool GetUseSeriesDetails() + { + return m_UseSeriesDetails; + } + /// \brief This function will add the following DICOM tag as being part of a + /// 'fake' uid. This is usefull when the Serie UID is not enough to disseminate + /// into multiple sub serie when needed: + /// 0020 0011 Series Number + /// 0018 0024 Sequence Name + /// 0018 0050 Slice Thickness + /// 0028 0010 Rows + /// 0028 0011 Columns + void CreateDefaultUniqueSeriesIdentifier(); + void AddSeriesDetail(uint16_t group, uint16_t elem, bool convert); - - std::string CreateUniqueSeriesIdentifier( File * inFile ); - + std::string CreateUserDefinedFileIdentifier( File * inFile ); + + /// \brief Create a string that uniquely identifies a series. By default + // uses the SeriesUID. If UseSeriesDetails(true) has been called, + // then additional identifying information is used. + std::string CreateUniqueSeriesIdentifier( File * inFile ); /** * \brief Sets the LoadMode as a boolean string. @@ -144,7 +169,7 @@ public: XCoherentFileSetmap SplitOnOrientation(FileList *fileSet); XCoherentFileSetmap SplitOnPosition(FileList *fileSet); XCoherentFileSetmap SplitOnTagValue(FileList *fileSet, - uint16_t group, uint16_t elem); + uint16_t group, uint16_t element); protected : SerieHelper(); @@ -164,11 +189,13 @@ private: SingleSerieUIDFileSetmap SingleSerieUIDFileSetHT; SingleSerieUIDFileSetmap::iterator ItFileSetHt; - + +#ifndef GDCM_LEGACY_REMOVE typedef std::pair Rule; typedef std::vector SerieRestrictions; SerieRestrictions Restrictions; - +#endif + // New style for (extented) Rules typedef struct { uint16_t group; @@ -178,7 +205,8 @@ private: } ExRule; typedef std::vector SerieExRestrictions; SerieExRestrictions ExRestrictions; - + SerieExRestrictions ExRefine; + typedef struct { uint16_t group; uint16_t elem; @@ -187,7 +215,6 @@ private: typedef std::vector SeriesExDetails; SeriesExDetails ExDetails; - bool m_UseSeriesDetails; /// \brief Bit string integer (each one considered as a boolean) /// Bit 0 : Skip Sequences, if possible @@ -201,9 +228,11 @@ private: /// \brief If user knows more about his images than gdcm does, /// he may supply his own comparison function. - BOOL_FUNCTION_PFILE_PFILE_POINTER UserLessThanFunction; + BOOL_FUNCTION_PFILE_PFILE_POINTER UserLessThanFunction; + + void Sort(FileList *fileList, bool (*pt2Func)( File *file1, File *file2) ); - void Sort(FileList *fileList, bool (*pt2Func)( File *file1, File *file2) ); + bool m_UseSeriesDetails; }; } // end namespace gdcm diff --git a/src/gdcmUtil.cxx b/src/gdcmUtil.cxx index 19895c1f..6d474c2e 100644 --- a/src/gdcmUtil.cxx +++ b/src/gdcmUtil.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmUtil.cxx,v $ Language: C++ - Date: $Date: 2006/01/10 15:54:03 $ - Version: $Revision: 1.182 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.183 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -497,8 +497,8 @@ std::string Util::DicomString(const char *s) /** * \brief Safely check the equality of two Dicom String: * - Both strings should be of even length - * - We allow padding of even length string by either - * a null character of a space + * - We allow padding of even length string by either + * a null character of a space */ bool Util::DicomStringEqual(const std::string &s1, const char *s2) { @@ -515,7 +515,7 @@ bool Util::DicomStringEqual(const std::string &s1, const char *s2) /** * \brief Safely compare two Dicom String: * - Both strings should be of even length - * - We allow padding of even length string by either + * - We allow padding of even length string by either * a null character of a space */ bool Util::CompareDicomString(const std::string &s1, const char *s2, int op) @@ -570,6 +570,29 @@ bool Util::CompareDicomString(const std::string &s1, const char *s2, int op) OUT AsnObjectIdentifier * supportedView); #endif //_WIN32 +#ifdef __sgi +static int SGIGetMacAddress(unsigned char *addr) +{ + FILE *f = popen("/etc/nvram eaddr","r"); + if(f == 0) + { + return -1; + } + unsigned int x[6]; + if(fscanf(f,"%02x:%02x:%02x:%02x:%02x:%02x", + x,x+1,x+2,x+3,x+4,x+5) != 6) + { + pclose(f); + return -1; + } + for(unsigned int i = 0; i < 6; i++) + { + addr[i] = static_cast(x[i]); + } + return 0; +} +#endif + /// \brief gets current M.A.C adress (for internal use only) int GetMacAddrSys ( unsigned char *addr ); int GetMacAddrSys ( unsigned char *addr ) @@ -702,6 +725,10 @@ int GetMacAddrSys ( unsigned char *addr ) return 0; #endif //Win32 version +#if defined(__sgi) + return SGIGetMacAddress(addr); +#endif // __sgi + // implementation for POSIX system #if defined(CMAKE_HAVE_NET_IF_ARP_H) && defined(__sun) @@ -985,7 +1012,6 @@ std::ostream &binary_write(std::ostream &os, const uint32_t &val) #endif //GDCM_WORDS_BIGENDIAN } - /** * \brief binary_write binary_write * @param os ostream to write to @@ -1013,7 +1039,6 @@ std::ostream &binary_write(std::ostream &os, const double &val) #endif //GDCM_WORDS_BIGENDIAN } - /** * \brief binary_write binary_write * @param os ostream to write to diff --git a/src/gdcmValidator.cxx b/src/gdcmValidator.cxx index c6cc6958..ff1b532f 100644 --- a/src/gdcmValidator.cxx +++ b/src/gdcmValidator.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmValidator.cxx,v $ Language: C++ - Date: $Date: 2005/11/21 09:43:43 $ - Version: $Revision: 1.13 $ + Date: $Date: 2006/02/16 20:06:15 $ + Version: $Revision: 1.14 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -20,9 +20,9 @@ #include "gdcmElementSet.h" #include "gdcmDataEntry.h" #include "gdcmUtil.h" +#include "gdcmDebug.h" // hidden way to include sstream #include -#include namespace gdcm { @@ -43,11 +43,11 @@ Validator::~Validator() bool CheckVM(DataEntry *entry) { // Don't waste time checking tags where VM is OB and OW, since we know - // it's allways 1, whatever the actual length (found on disc) + // it's always 1, whatever the actual length (found on disc) if ( entry->GetVR() == "OB" || entry->GetVR() == "OW" ) return true; - + const std::string &s = entry->GetString(); unsigned int n = Util::CountSubstring( s , "\\"); -- 2.45.1