From: regrain Date: Mon, 19 Jan 2004 11:20:17 +0000 (+0000) Subject: * removal of file gdcmHeader2.cxx X-Git-Tag: Version0.4~92 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=bafdfafe6c1b30607035fc4018c0405169b348e8;p=gdcm.git * removal of file gdcmHeader2.cxx * split class gdcmHeader into gdcmParser and gdcmHeader, with gdcmHeader inheriting from gdcmParser. This split is to prepare the integration of dicom dir parsing -- BeNours --- diff --git a/ChangeLog b/ChangeLog index beda1dfa..5d905940 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-01-19 Benoit Regrain + * removal of file gdcmHeader2.cxx + * split class gdcmHeader into gdcmParser and gdcmHeader, with gdcmHeader + inheriting from gdcmParser. This split is to prepare the integration + of dicom dir parsing + * + 2004-01-16 Jean-Pierre Roux * removal of class gdcmHeaderEntrySet * removal of files gdcmHeaderEntrySet.cxx, gdcmHeaderEntrySet.h diff --git a/gdcmPython/__init__.py b/gdcmPython/__init__.py index bba4be47..7d6390e7 100644 --- a/gdcmPython/__init__.py +++ b/gdcmPython/__init__.py @@ -70,9 +70,10 @@ except ImportError,e: raise ImportError, "gdcm extension not imported." ### Expose only the necessary stuff -gdcmHeader = gdcm.gdcmHeader -gdcmDictSet = gdcm.gdcmDictSet -gdcmFile = gdcm.gdcmFile +gdcmDictSet = gdcm.gdcmDictSet +gdcmHeader = gdcm.gdcmHeader +gdcmHeaderHelper = gdcm.gdcmHeaderHelper +gdcmFile = gdcm.gdcmFile def GetPubDictTagNames(): return gdcm.cvar.gdcmGlob.GetDicts().GetPubDictTagNames() diff --git a/gdcmPython/gdcm.i b/gdcmPython/gdcm.i index 11b81804..3f68d08e 100644 --- a/gdcmPython/gdcm.i +++ b/gdcmPython/gdcm.i @@ -4,6 +4,7 @@ #include "gdcmDictEntry.h" #include "gdcmDict.h" #include "gdcmDictSet.h" +#include "gdcmParser.h" #include "gdcmHeaderEntry.h" #include "gdcmHeader.h" #include "gdcmHeaderHelper.h" @@ -109,6 +110,7 @@ extern gdcmGlobal gdcmGlob; %include "gdcmDictEntry.h" %include "gdcmDict.h" %include "gdcmDictSet.h" +%include "gdcmParser.h" %include "gdcmHeaderEntry.h" %include "gdcmHeader.h" %include "gdcmHeaderHelper.h" diff --git a/src/gdcm.h b/src/gdcm.h index 7aa9fc3a..a3d7ad5c 100644 --- a/src/gdcm.h +++ b/src/gdcm.h @@ -20,6 +20,8 @@ #include "gdcmDict.h" #include "gdcmDictSet.h" +#include "gdcmParser.h" + #include "gdcmHeaderEntry.h" #include "gdcmHeader.h" diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 888c5758..858ee0cb 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -124,7 +124,7 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { int nb; std::string str_nb; - str_nb=Header->GetPubEntryByNumber(0x0028,0x0100); + str_nb=Header->GetEntryByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; } else { @@ -134,7 +134,7 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { lgrTotale = lgrTotaleRaw = Header->GetXSize() * Header->GetYSize() * Header->GetZSize() * (nb/8)* Header->GetSamplesPerPixel(); std::string str_PhotometricInterpretation = - Header->GetPubEntryByNumber(0x0028,0x0004); + Header->GetEntryByNumber(0x0028,0x0004); /*if ( str_PhotometricInterpretation == "PALETTE COLOR " )*/ // pb when undealt Segmented Palette Color @@ -233,11 +233,11 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { // CreateOrReplaceIfExist ? std::string spp = "3"; // Samples Per Pixel - Header->SetPubEntryByNumber(spp,0x0028,0x0002); + Header->SetEntryByNumber(spp,0x0028,0x0002); std::string rgb= "RGB "; // Photometric Interpretation - Header->SetPubEntryByNumber(rgb,0x0028,0x0004); + Header->SetEntryByNumber(rgb,0x0028,0x0004); std::string planConfig = "0"; // Planar Configuration - Header->SetPubEntryByNumber(planConfig,0x0028,0x0006); + Header->SetEntryByNumber(planConfig,0x0028,0x0006); } else { // need to make RGB Pixels (?) @@ -251,7 +251,7 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { // Segmented xxx Palette Color are *more* than 65535 long ?!? std::string rgb= "MONOCHROME1 "; // Photometric Interpretation - Header->SetPubEntryByNumber(rgb,0x0028,0x0004); + Header->SetEntryByNumber(rgb,0x0028,0x0004); } // TODO : Drop Palette Color out of the Header? return lgrTotale; @@ -316,21 +316,21 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) { (void)ReadPixelData(destination); // Number of Bits Allocated for storing a Pixel - str_nb = Header->GetPubEntryByNumber(0x0028,0x0100); + str_nb = Header->GetEntryByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; } else { nb = atoi(str_nb.c_str() ); } // Number of Bits actually used - str_nbu=Header->GetPubEntryByNumber(0x0028,0x0101); + str_nbu=Header->GetEntryByNumber(0x0028,0x0101); if (str_nbu == GDCM_UNFOUND ) { nbu = nb; } else { nbu = atoi(str_nbu.c_str() ); } // High Bit Position - str_highBit=Header->GetPubEntryByNumber(0x0028,0x0102); + str_highBit=Header->GetEntryByNumber(0x0028,0x0102); if (str_highBit == GDCM_UNFOUND ) { highBit = nb - 1; } else { @@ -339,7 +339,7 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) { // Pixel sign // 0 = Unsigned // 1 = Signed - str_signe=Header->GetPubEntryByNumber(0x0028,0x0103); + str_signe=Header->GetEntryByNumber(0x0028,0x0103); if (str_signe == GDCM_UNFOUND ) { signe = 0; // default is unsigned } else { @@ -397,7 +397,7 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) { // ------------------- std::string str_PhotometricInterpretation = - Header->GetPubEntryByNumber(0x0028,0x0004); + Header->GetEntryByNumber(0x0028,0x0004); if ( (str_PhotometricInterpretation == "MONOCHROME1 ") || (str_PhotometricInterpretation == "MONOCHROME2 ") ) { @@ -509,12 +509,12 @@ size_t gdcmFile::GetImageDataIntoVectorRaw (void* destination, size_t MaxSize) { // CreateOrReplaceIfExist ? std::string spp = "3"; // Samples Per Pixel - Header->SetPubEntryByNumber(spp,0x0028,0x0002); + Header->SetEntryByNumber(spp,0x0028,0x0002); std::string rgb="RGB "; // Photometric Interpretation - Header->SetPubEntryByNumber(rgb,0x0028,0x0004); + Header->SetEntryByNumber(rgb,0x0028,0x0004); std::string planConfig = "0"; // Planar Configuration - Header->SetPubEntryByNumber(planConfig,0x0028,0x0006); + Header->SetEntryByNumber(planConfig,0x0028,0x0006); // TODO : Drop Palette Color out of the Header? return lgrTotale; @@ -658,10 +658,10 @@ bool gdcmFile::WriteBase (std::string fileName, FileType type) { std::string rows, columns; if ( Header->GetFileType() == ACR_LIBIDO){ - rows = Header->GetPubEntryByNumber(0x0028, 0x0010); - columns = Header->GetPubEntryByNumber(0x0028, 0x0011); - Header->SetPubEntryByNumber(columns, 0x0028, 0x0010); - Header->SetPubEntryByNumber(rows , 0x0028, 0x0011); + rows = Header->GetEntryByNumber(0x0028, 0x0010); + columns = Header->GetEntryByNumber(0x0028, 0x0011); + Header->SetEntryByNumber(columns, 0x0028, 0x0010); + Header->SetEntryByNumber(rows , 0x0028, 0x0011); } // ----------------- End of Special Patch ---------------- @@ -674,8 +674,8 @@ bool gdcmFile::WriteBase (std::string fileName, FileType type) { // just after writting if (Header->GetFileType() == ACR_LIBIDO){ - Header->SetPubEntryByNumber(rows , 0x0028, 0x0010); - Header->SetPubEntryByNumber(columns, 0x0028, 0x0011); + Header->SetEntryByNumber(rows , 0x0028, 0x0010); + Header->SetEntryByNumber(columns, 0x0028, 0x0011); } // ----------------- End of Special Patch ---------------- @@ -834,7 +834,7 @@ bool gdcmFile::ReadPixelData(void* destination) { // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 int nb; - std::string str_nb=Header->GetPubEntryByNumber(0x0028,0x0100); + std::string str_nb=Header->GetEntryByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; } else { @@ -847,7 +847,7 @@ bool gdcmFile::ReadPixelData(void* destination) { int taille = Header->GetXSize() * Header->GetYSize() * Header->GetSamplesPerPixel(); long fragmentBegining; // for ftell, fseek - + bool jpg2000 = Header->IsJPEG2000(); bool jpgLossless = Header->IsJPEGLossless(); diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index fc306970..024862dd 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -4,30 +4,30 @@ #include #include -// For nthos: +/*// For nthos: #ifdef _MSC_VER -#include + #include #else -#include -#endif + #include +#endif*/ #include // for isalpha -#ifdef GDCM_NO_ANSI_STRING_STREAM +/*#ifdef GDCM_NO_ANSI_STRING_STREAM # include # define ostringstream ostrstream # else # include -#endif +#endif*/ #include "gdcmUtil.h" #include "gdcmTS.h" //----------------------------------------------------------------------------- // Refer to gdcmHeader::CheckSwap() -const unsigned int gdcmHeader::HEADER_LENGTH_TO_READ = 256; +//const unsigned int gdcmHeader::HEADER_LENGTH_TO_READ = 256; -// Refer to gdcmHeader::SetMaxSizeLoadElementValue() -const unsigned int gdcmHeader::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096; +// Refer to gdcmHeader::SetMaxSizeLoadEntry() +//const unsigned int gdcmHeader::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096; //----------------------------------------------------------------------------- // Constructor / Destructor @@ -45,22 +45,9 @@ const unsigned int gdcmHeader::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096; */ gdcmHeader::gdcmHeader(const char *InFilename, bool exception_on_error, - bool enable_sequences ) { - if (enable_sequences) - enableSequences = 1; - else - enableSequences = 0; - - SetMaxSizeLoadElementValue(MAX_SIZE_LOAD_ELEMENT_VALUE); - filename = InFilename; - Initialise(); - if ( !OpenFile(exception_on_error)) - return; - ParseHeader(); - LoadHeaderEntries(); - CloseFile(); - wasUpdated = 0; // will be set to 1 if user adds an entry - printLevel = 1; // 'Heavy' header print by default + bool enable_sequences ): + gdcmParser(InFilename,exception_on_error,enable_sequences) +{ } /** @@ -68,9 +55,9 @@ gdcmHeader::gdcmHeader(const char *InFilename, * \brief * @param exception_on_error */ -gdcmHeader::gdcmHeader(bool exception_on_error) { - SetMaxSizeLoadElementValue(MAX_SIZE_LOAD_ELEMENT_VALUE); - Initialise(); +gdcmHeader::gdcmHeader(bool exception_on_error) : + gdcmParser(exception_on_error) +{ } /** @@ -78,139 +65,13 @@ gdcmHeader::gdcmHeader(bool exception_on_error) { * \brief Canonical destructor. */ gdcmHeader::~gdcmHeader (void) { - dicom_vr = (gdcmVR*)0; - Dicts = (gdcmDictSet*)0; - RefPubDict = (gdcmDict*)0; - RefShaDict = (gdcmDict*)0; - return; } //----------------------------------------------------------------------------- // Print -/** - * \ingroup gdcmHeader - * \brief Prints the Header Entries (Dicom Elements) - * both from the H Table and the chained list - * @return - */ -void gdcmHeader::PrintPubEntry(std::ostream & os) { - Print(os); -} - -/** - * \ingroup gdcmHeader - * \brief Prints The Dict Entries of THE public Dicom Dictionnry - * @return - */ -void gdcmHeader::PrintPubDict(std::ostream & os) { - RefPubDict->Print(os); -} - //----------------------------------------------------------------------------- // Public -/** - * \ingroup gdcmHeader - * \brief This predicate, based on hopefully reasonable heuristics, - * decides whether or not the current gdcmHeader was properly parsed - * and contains the mandatory information for being considered as - * a well formed and usable Dicom/Acr File. - * @return true when gdcmHeader is the one of a reasonable Dicom/Acr file, - * false otherwise. - */ -bool gdcmHeader::IsReadable(void) { - std::string res = GetEntryByNumber(0x0028, 0x0005); - if ( res != GDCM_UNFOUND && atoi(res.c_str()) > 4 ) { - return false; // Image Dimensions - } - - if ( !GetHeaderEntryByNumber(0x0028, 0x0100) ) - return false; // "Bits Allocated" - if ( !GetHeaderEntryByNumber(0x0028, 0x0101) ) - return false; // "Bits Stored" - if ( !GetHeaderEntryByNumber(0x0028, 0x0102) ) - return false; // "High Bit" - if ( !GetHeaderEntryByNumber(0x0028, 0x0103) ) - return false; // "Pixel Representation" - return true; -} - -/** - * \ingroup gdcmHeader - * \brief Determines if the Transfer Syntax was already encountered - * and if it corresponds to a ImplicitVRLittleEndian one. - * - * @return True when ImplicitVRLittleEndian found. False in all other cases. - */ -bool gdcmHeader::IsImplicitVRLittleEndianTransferSyntax(void) { - gdcmHeaderEntry *Element = GetHeaderEntryByNumber(0x0002, 0x0010); - if ( !Element ) - return false; - LoadHeaderEntrySafe(Element); - - std::string Transfer = Element->GetValue(); - if ( Transfer == "1.2.840.10008.1.2" ) - return true; - return false; -} - -/** - * \ingroup gdcmHeader - * \brief Determines if the Transfer Syntax was already encountered - * and if it corresponds to a ExplicitVRLittleEndian one. - * - * @return True when ExplicitVRLittleEndian found. False in all other cases. - */ -bool gdcmHeader::IsExplicitVRLittleEndianTransferSyntax(void) { - gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010); - if ( !Element ) - return false; - LoadHeaderEntrySafe(Element); - - std::string Transfer = Element->GetValue(); - if ( Transfer == "1.2.840.10008.1.2.1" ) - return true; - return false; -} - -/** - * \ingroup gdcmHeader - * \brief Determines if the Transfer Syntax was already encountered - * and if it corresponds to a DeflatedExplicitVRLittleEndian one. - * - * @return True when DeflatedExplicitVRLittleEndian found. False in all other cases. - */ -bool gdcmHeader::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) { - gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010); - if ( !Element ) - return false; - LoadHeaderEntrySafe(Element); - - std::string Transfer = Element->GetValue(); - if ( Transfer == "1.2.840.10008.1.2.1.99" ) - return true; - return false; -} - -/** - * \ingroup gdcmHeader - * \brief Determines if the Transfer Syntax was already encountered - * and if it corresponds to a Explicit VR Big Endian one. - * - * @return True when big endian found. False in all other cases. - */ -bool gdcmHeader::IsExplicitVRBigEndianTransferSyntax(void) { - gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010); - if ( !Element ) - return false; - LoadHeaderEntrySafe(Element); - - std::string Transfer = Element->GetValue(); - if ( Transfer == "1.2.840.10008.1.2.2" ) //1.2.2 ??? A verifier ! - return true; - return false; -} - /** * \ingroup gdcmHeader * \brief Determines if the Transfer Syntax was already encountered @@ -362,16 +223,6 @@ bool gdcmHeader::IsDicomV3(void) { return (GetHeaderEntryByNumber(0x0002, 0x0010) != NULL); } -/** - * \ingroup gdcmHeader - * \brief returns the File Type - * (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown) - * @return - */ -FileType gdcmHeader::GetFileType(void) { - return(filetype); -} - /** * \ingroup gdcmHeader * \brief Retrieve the number of columns of image. @@ -738,24 +589,24 @@ unsigned char * gdcmHeader::GetLUTRGBA(void) { nbitsB =atoi(tokens[2].c_str()); tokens.clear(); -// Load LUTs into memory, (as they were stored on disk) + // Load LUTs into memory, (as they were stored on disk) unsigned char *lutR = (unsigned char *) - GetPubEntryVoidAreaByNumber(0x0028,0x1201); + GetEntryVoidAreaByNumber(0x0028,0x1201); unsigned char *lutG = (unsigned char *) - GetPubEntryVoidAreaByNumber(0x0028,0x1202); + GetEntryVoidAreaByNumber(0x0028,0x1202); unsigned char *lutB = (unsigned char *) - GetPubEntryVoidAreaByNumber(0x0028,0x1203); + GetEntryVoidAreaByNumber(0x0028,0x1203); if (!lutR || !lutG || !lutB ) { return NULL; } - // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT + // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT - unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); // 256 * 4 (R, G, B, Alpha) - if (!LUTRGBA) { - return NULL; - } - memset(LUTRGBA, 0, 1024); + unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); // 256 * 4 (R, G, B, Alpha) + if (!LUTRGBA) { + return NULL; + } + memset(LUTRGBA, 0, 1024); // Bits Allocated int nb; std::string str_nb = GetEntryByNumber(0x0028,0x0100); @@ -764,12 +615,12 @@ unsigned char * gdcmHeader::GetLUTRGBA(void) { } else { nb = atoi(str_nb.c_str() ); } - int mult; - - if (nbitsR==16 && nb==8) // when LUT item size is different than pixel size - mult=2; // high byte must be = low byte - else // See PS 3.3-2003 C.11.1.1.2 p 619 - mult=1; + int mult; + + if (nbitsR==16 && nb==8) // when LUT item size is different than pixel size + mult=2; // high byte must be = low byte + else // See PS 3.3-2003 C.11.1.1.2 p 619 + mult=1; // if we get a black image, let's just remove the '+1' // from 'i*mult+1' and check again @@ -777,34 +628,34 @@ unsigned char * gdcmHeader::GetLUTRGBA(void) { // to see which byte is ==0 (first one, or second one) // and fix the code // We give up the checking to avoid some overhead - unsigned char *a; - int i; - - a = LUTRGBA+0; - for(i=0;iGetTagByName(tagName); - if( dictEntry == NULL) - return GDCM_UNFOUND; - - return(GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement())); -} - -/** - * \ingroup gdcmHeader - * \brief Searches within the elements parsed with the file Header for - * the element value representation of a given tag. - * - * Obtaining the VR (Value Representation) might be needed by caller - * to convert the string typed content to caller's native type - * (think of C++ vs Python). The VR is actually of a higher level - * of semantics than just the native C++ type. - * @param tagName name of the searched element. - * @return Corresponding element value representation when it exists, - * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetPubEntryVRByName(std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); - if( dictEntry == NULL) - return GDCM_UNFOUND; - - gdcmHeaderEntry* elem = GetHeaderEntryByNumber(dictEntry->GetGroup(), - dictEntry->GetElement()); - return elem->GetVR(); -} - - -/** - * \ingroup gdcmHeader - * \brief Searches within the public dictionary for element value - * representation of a given tag. - * - * Obtaining the VR (Value Representation) might be needed by caller - * to convert the string typed content to caller's native type - * (think of C++ vs Python). The VR is actually of a higher level - * of semantics than just the native C++ type. - * @param group Group of the researched tag. - * @param element Element of the researched tag. - * @return Corresponding element value representation when it exists, - * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetPubEntryVRByNumber(guint16 group, guint16 element) { - gdcmHeaderEntry* elem = GetHeaderEntryByNumber(group, element); - if ( !elem ) - return GDCM_UNFOUND; - return elem->GetVR(); -} - -/** - * \ingroup gdcmHeader - * \brief Accesses an existing gdcmHeaderEntry (i.e. a Dicom Element) - * in the PubHeaderEntrySet of this instance - * through tag name and modifies it's content with the given value. - * @param content new value to substitute with - * @param tagName name of the Header Entry (Dicom Element) to be modified - */ -bool gdcmHeader::SetPubEntryByName(std::string content, std::string tagName) { - //return ( PubHeaderEntrySet.SetHeaderEntryByName (content, tagName) ); - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); - if( dictEntry == NULL) - return false; - return(SetEntryByNumber(content, - dictEntry->GetGroup(), - dictEntry->GetElement())); -} - -/** - * \ingroup gdcmHeader - * \brief Accesses an existing gdcmHeaderEntry (i.e. a Dicom Element) - * through it's (group, element) and modifies it's content with - * the given value. - * @param content new value to substitute with - * @param group group of the Dicom Element to modify - * @param element element of the Dicom Element to modify - */ -bool gdcmHeader::SetPubEntryByNumber(std::string content, - guint16 group, - guint16 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHT.count(key)) - return false; - int l = content.length(); - if(l%2) { // Odd length are padded with a space (020H). - l++; - content = content + '\0'; - } - - //tagHT[key]->SetValue(content); - gdcmHeaderEntry * a; - IterHT p; - TagHeaderEntryHT::iterator p2; - // DO NOT remove the following lines : they explain the stuff - //p= tagHT.equal_range(key); // get a pair of iterators first-last synonym - //p2=p.first; // iterator on the first synonym - //a=p2->second; // H Table target column (2-nd col) - - // or, easier : - a = ((tagHT.equal_range(key)).first)->second; - - a-> SetValue(content); - - //std::string vr = tagHT[key]->GetVR(); - std::string vr = a->GetVR(); - - guint32 lgr; - if( (vr == "US") || (vr == "SS") ) - lgr = 2; - else if( (vr == "UL") || (vr == "SL") ) - lgr = 4; - else - lgr = l; - //tagHT[key]->SetLength(lgr); - a->SetLength(lgr); - return true; -} - -/** - * \ingroup gdcmHeader - * \brief Accesses an existing gdcmHeaderEntry (i.e. a Dicom Element) - * through it's (group, element) and modifies it's content with - * the given value. - * \warning Don't use any longer : use SetPubEntryByNumber - * @param content new value to substitute with - * @param group group of the Dicom Element to modify - * @param element element of the Dicom Element to modify - */ -bool gdcmHeader::SetEntryByNumber(std::string content, - guint16 group, - guint16 element) { - return SetPubEntryByNumber(content, group, element); -} - -/** - * \ingroup gdcmHeader - * \brief Accesses an existing gdcmHeaderEntry (i.e. a Dicom Element) - * in the PubHeaderEntrySet of this instance - * through it's (group, element) and modifies it's length with - * the given value. - * \warning Use with extreme caution. - * @param length new length to substitute with - * @param group group of the ElVal to modify - * @param element element of the ElVal to modify - * @return 1 on success, 0 otherwise. - */ - -bool gdcmHeader::SetPubEntryLengthByNumber(guint32 length, - guint16 group, guint16 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHT.count(key)) - return false; - if (length%2) length++; // length must be even - //tagHT[key]->SetLength(length); - ( ((tagHT.equal_range(key)).first)->second )->SetLength(length); - - return true ; -} - -/** - * \ingroup gdcmHeader - * \brief Accesses an existing gdcmHeaderEntry (i.e. a Dicom Element) - * in the PubHeaderEntrySet of this instance - * through it's (group, element) and modifies it's length with - * the given value. - * \warning Don't use any longer : use SetPubEntryLengthByNumber - * @param length new length to substitute with - * @param group group of the ElVal to modify - * @param element element of the ElVal to modify - * @return 1 on success, 0 otherwise. - */ - -bool gdcmHeader::SetEntryLengthByNumber(guint32 length, - guint16 group, guint16 element) { - return SetPubEntryLengthByNumber( length, group,element); -} -/** - * \ingroup gdcmHeader - * \brief Searches within Header Entries (Dicom Elements) parsed with - * the public and private dictionaries - * for the element value of a given tag. - * \warning Don't use any longer : use GetPubEntryByName - * @param tagName name of the searched element. - * @return Corresponding element value when it exists, - * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetEntryByName(std::string tagName) { - return GetPubEntryByName(tagName); -} - -/** - * \ingroup gdcmHeader - * \brief Searches within Header Entries (Dicom Elements) parsed with - * the public and private dictionaries - * for the element value representation of a given tag. - * - * Obtaining the VR (Value Representation) might be needed by caller - * to convert the string typed content to caller's native type - * (think of C++ vs Python). The VR is actually of a higher level - * of semantics than just the native C++ type. - * @param tagName name of the searched element. - * @return Corresponding element value representation when it exists, - * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetEntryVRByName(std::string tagName) { - return GetPubEntryVRByName(tagName); -} - -/** - * \ingroup gdcmHeader - * \brief Searches within Header Entries (Dicom Elements) parsed with - * the public and private dictionaries - * for the element value representation of a given tag. - * @param group Group of the searched tag. - * @param element Element of the searched tag. - * @return Corresponding element value representation when it exists, - * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetEntryByNumber(guint16 group, guint16 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHT.count(key)) - return GDCM_UNFOUND; - return tagHT.find(key)->second->GetValue(); -} - -/** - * \ingroup gdcmHeader - * \brief Searches within the public dictionary for element value of - * a given tag. - * @param group Group of the researched tag. - * @param element Element of the researched tag. - * @return Corresponding element value when it exists, and the string - * GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetPubEntryByNumber(guint16 group, guint16 element) { - return GetEntryByNumber(group, element); -} - - -/** - * \ingroup gdcmHeader - * \brief Searches within Header Entries (Dicom Elements) parsed with - * the public and private dictionaries - * for the element value representation of a given tag.. - * - * Obtaining the VR (Value Representation) might be needed by caller - * to convert the string typed content to caller's native type - * (think of C++ vs Python). The VR is actually of a higher level - * of semantics than just the native C++ type. - * @param group Group of the searched tag. - * @param element Element of the searched tag. - * @return Corresponding element value representation when it exists, - * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. - */ -std::string gdcmHeader::GetEntryVRByNumber(guint16 group, guint16 element) { - return GetPubEntryVRByNumber(group, element); -} - -/** - * \ingroup gdcmHeader - * \brief Sets the value (string) of the Header Entry (Dicom Element) - * @param content string value of the Dicom Element - * @param tagName name of the searched Dicom Element. - * @return true when found - */ -bool gdcmHeader::SetEntryByName(std::string content,std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); - if( dictEntry == NULL) - return false; - - - TagKey key = gdcmDictEntry::TranslateToKey(dictEntry->GetGroup(), - dictEntry->GetElement()); - if ( GetPubEntry().count(key) == 0 ) - return false; - int l = content.length(); - if(l%2) { // Odd length are padded with a space (020H). - l++; - content = content + '\0'; - } - - //tagHt[key]->SetValue(content); - gdcmHeaderEntry * a; - IterHT p; - TagHeaderEntryHT::iterator p2; - // DO NOT remove the following lines : they explain how the stuff works - //p= tagHt.equal_range(key); // get a pair of iterators first-last synonym - //p2=p.first; // iterator on the first synonym - //a=p2->second; // H Table target column (2-nd col) - // or, easier : - a = ((GetPubEntry().equal_range(key)).first)->second; - a-> SetValue(content); - std::string vr = a->GetVR(); - - guint32 lgr; - if( (vr == "US") || (vr == "SS") ) - lgr = 2; - else if( (vr == "UL") || (vr == "SL") ) - lgr = 4; - else - lgr = l; - a->SetLength(lgr); - return true; -} - -/** - * \ingroup gdcmHeader - * \brief opens the file - * @param exception_on_error - * @return - */ -FILE *gdcmHeader::OpenFile(bool exception_on_error) - throw(gdcmFileError) { - fp=fopen(filename.c_str(),"rb"); - if(exception_on_error) { - if(!fp) - throw gdcmFileError("gdcmHeader::gdcmHeader(const char *, bool)"); - } - - if ( fp ) { - guint16 zero; - fread(&zero, (size_t)2, (size_t)1, fp); - - //ACR -- or DICOM with no Preamble -- - if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200) - return(fp); - - //DICOM - fseek(fp, 126L, SEEK_CUR); - char dicm[4]; - fread(dicm, (size_t)4, (size_t)1, fp); - if( memcmp(dicm, "DICM", 4) == 0 ) - return(fp); - - fclose(fp); - dbg.Verbose(0, "gdcmHeader::gdcmHeader not DICOM/ACR", filename.c_str()); - } - else { - dbg.Verbose(0, "gdcmHeader::gdcmHeader cannot open file", filename.c_str()); - } - return(NULL); -} - -/** - * \ingroup gdcmHeader - * \brief closes the file - * @return TRUE if the close was successfull - */ -bool gdcmHeader::CloseFile(void) { - int closed = fclose(fp); - fp = (FILE *)0; - if (! closed) - return false; - return true; -} - -/** - * \ingroup gdcmHeader - * \brief Parses the header of the file but WITHOUT loading element values. - */ -void gdcmHeader::ParseHeader(bool exception_on_error) throw(gdcmFormatError) { - gdcmHeaderEntry * newHeaderEntry = (gdcmHeaderEntry *)0; - - rewind(fp); - CheckSwap(); - while ( (newHeaderEntry = ReadNextHeaderEntry()) ) { - SkipHeaderEntry(newHeaderEntry); - Add(newHeaderEntry); - } -} - - - -/** - * \ingroup gdcmHeader - * \brief - * @param fp file pointer on an already open file - * @param type type of the File to be written - * (ACR-NEMA, ExplicitVR, ImplicitVR) - * @return always "True" ?! - */ -bool gdcmHeader::Write(FILE * fp, FileType type) { - -// ============== -// TODO The stuff has been rewritten using the chained list instead -// of the H table -// so we could remove the GroupHT from the gdcmHeader -// To be checked -// ============= - - // TODO : move the following lines (and a lot of others, to be written) - // to a future function CheckAndCorrectHeader - - // Question : - // Comment pourrait-on savoir si le DcmHeader vient d'un fichier DicomV3 ou non - // (FileType est un champ de gdcmHeader ...) - // WARNING : Si on veut ecrire du DICOM V3 a partir d'un DcmHeader ACR-NEMA - // no way - // a moins de se livrer a un tres complique ajout des champs manquants. - // faire un CheckAndCorrectHeader (?) - - - if (type == ImplicitVR) { - std::string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; - ReplaceOrCreateByNumber(implicitVRTransfertSyntax,0x0002, 0x0010); - - //FIXME Refer to standards on page 21, chapter 6.2 "Value representation": - // values with a VR of UI shall be padded with a single trailing null - // Dans le cas suivant on doit pader manuellement avec un 0 - - SetEntryLengthByNumber(18, 0x0002, 0x0010); - } - - if (type == ExplicitVR) { - std::string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1"; - ReplaceOrCreateByNumber(explicitVRTransfertSyntax,0x0002, 0x0010); - - //FIXME Refer to standards on page 21, chapter 6.2 "Value representation": - // values with a VR of UI shall be padded with a single trailing null - // Dans le cas suivant on doit pader manuellement avec un 0 - - SetEntryLengthByNumber(20, 0x0002, 0x0010); - } - - - if ( (type == ImplicitVR) || (type == ExplicitVR) ) - UpdateGroupLength(false,type); - if ( type == ACR) - UpdateGroupLength(true,ACR); - - WriteEntries(type, fp); - return(true); - } - /** * \ingroup gdcmFile * \brief Sets the Pixel Area size in the Header @@ -1295,1198 +701,13 @@ void gdcmHeader::SetImageDataSize(size_t ImageDataSize) { ImageDataSize+=8; sprintf(car,"%d",ImageDataSize); content1=car; - SetPubEntryByNumber(content1, 0x7fe0, 0x0000); -} - -/** - * \ingroup gdcmHeader - * \brief Modifies the value of a given Header Entry (Dicom Element) - * if it exists; Creates it with the given value if it doesn't - * @param Value passed as a std::string - * @param Group - * @param Elem - * \return boolean - */ -bool gdcmHeader::ReplaceOrCreateByNumber(std::string Value, - guint16 Group, guint16 Elem ) { - - if (CheckIfExistByNumber(Group, Elem) == 0) { - gdcmHeaderEntry* a =NewHeaderEntryByNumber(Group, Elem); - if (a == NULL) - return false; - Add(a); - } - SetPubEntryByNumber(Value, Group, Elem); - return(true); -} - -/** - * \ingroup gdcmHeader - * \brief Modifies the value of a given Header Entry (Dicom Element) - * if it exists; Creates it with the given value if it doesn't - * @param Value passed as a char* - * @param Group - * @param Elem - * \return boolean - * - */ -bool gdcmHeader::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) { - - gdcmHeaderEntry* nvHeaderEntry=NewHeaderEntryByNumber(Group, Elem); - // TODO : check if fails - Add(nvHeaderEntry); - std::string v = Value; - SetEntryByNumber(v, Group, Elem); - return(true); -} - -/** - * \ingroup gdcmHeader - * \brief Set a new value if the invoked element exists - * Seems to be useless !!! - * @param Value - * @param Group - * @param Elem - * \return boolean - */ -bool gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) { - - std::string v = Value; - SetEntryByNumber(v, Group, Elem); - return true; -} - -/** - * \ingroup gdcmHeader - * \brief Swaps back the bytes of 4-byte long integer accordingly to - * processor order. - * @return The properly swaped 32 bits integer. - */ -guint32 gdcmHeader::SwapLong(guint32 a) { - switch (sw) { - case 0 : - break; - case 4321 : - a=( ((a<<24) & 0xff000000) | ((a<<8) & 0x00ff0000) | - ((a>>8) & 0x0000ff00) | ((a>>24) & 0x000000ff) ); - break; - - case 3412 : - a=( ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) ); - break; - - case 2143 : - a=( ((a<<8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff) ); - break; - default : - dbg.Error(" gdcmHeader::SwapLong : unset swap code"); - a=0; - } - return(a); -} - -/** - * \ingroup gdcmHeader - * \brief Swaps the bytes so they agree with the processor order - * @return The properly swaped 16 bits integer. - */ -guint16 gdcmHeader::SwapShort(guint16 a) { - if ( (sw==4321) || (sw==2143) ) - a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff)); - return (a); + SetEntryByNumber(content1, 0x7fe0, 0x0000); } //----------------------------------------------------------------------------- // Protected -/** - * \ingroup gdcmHeader - * \brief retrieves a Dicom Element (the first one) using (group, element) - * \ warning (group, element) IS NOT an identifier inside the Dicom Header - * if you think it's NOT UNIQUE, check the count number - * and use iterators to retrieve ALL the Dicoms Elements within - * a given couple (group, element) - * @param group Group number of the searched Dicom Element - * @param element Element number of the searched Dicom Element - * @return - */ -gdcmHeaderEntry* gdcmHeader::GetHeaderEntryByNumber(guint16 group, guint16 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHT.count(key)) - return NULL; - return tagHT.find(key)->second; -} - - -/** - * \ingroup gdcmHeader - * \brief Searches within the Header Entries for a Dicom Element of - * a given tag. - * @param tagName name of the searched Dicom Element. - * @return Corresponding Dicom Element when it exists, and NULL - * otherwise. - */ - gdcmHeaderEntry *gdcmHeader::GetHeaderEntryByName(std::string tagName) { - gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName); - if( dictEntry == NULL) - return NULL; - - return(GetHeaderEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement())); -} - -/** - * \ingroup gdcmHeader - * \brief Checks if a given Dicom Element exists - * \ within the H table - * @param group Group number of the searched Dicom Element - * @param element Element number of the searched Dicom Element - * @return number of occurences - */ -int gdcmHeader::CheckIfExistByNumber(guint16 group, guint16 element ) { - std::string key = gdcmDictEntry::TranslateToKey(group, element ); - return (tagHT.count(key)); -} - -/** - * \ingroup gdcmHeader - * \brief Gets (from Header) the offset of a 'non string' element value - * \ (LoadElementValues has already be executed) - * @param Group - * @param Elem - * @return File Offset of the Element Value - */ -size_t gdcmHeader::GetPubEntryOffsetByNumber(guint16 Group, guint16 Elem) { - gdcmHeaderEntry* Entry = GetHeaderEntryByNumber(Group, Elem); - if (!Entry) { - dbg.Verbose(1, "gdcmHeader::GetHeaderEntryByNumber", - "failed to Locate gdcmHeaderEntry"); - return (size_t)0; - } - return Entry->GetOffset(); -} - -/** - * \ingroup gdcmHeader - * \brief Gets (from Header) a 'non string' element value - * \ (LoadElementValues has already be executed) - * @param Group - * @param Elem - * @return Pointer to the 'non string' area - */ -void * gdcmHeader::GetPubEntryVoidAreaByNumber(guint16 Group, guint16 Elem) { - gdcmHeaderEntry* Entry = GetHeaderEntryByNumber(Group, Elem); - if (!Entry) { - dbg.Verbose(1, "gdcmHeader::GetHeaderEntryByNumber", - "failed to Locate gdcmHeaderEntry"); - return (NULL); - } - return Entry->GetVoidArea(); -} - -/** - * \ingroup gdcmHeader - * \brief Loads (from disk) the element content - * when a string is not suitable - */ -void * gdcmHeader::LoadEntryVoidArea(guint16 Group, guint16 Elem) { - gdcmHeaderEntry * Element= GetHeaderEntryByNumber(Group, Elem); - if ( !Element ) - return NULL; - size_t o =(size_t)Element->GetOffset(); - fseek(fp, o, SEEK_SET); - int l=Element->GetLength(); - void * a = malloc(l); - if(!a) { - return NULL; - } - - SetVoidAreaByNumber(a, Group, Elem); - // TODO check the result - size_t l2 = fread(a, 1, l ,fp); - if(l != l2) { - free(a); - return NULL; - } - return a; -} - //----------------------------------------------------------------------------- // Private -/** - * \ingroup gdcmHeader - * \brief Loads the element values of all the Header Entries pointed in the - * public Chained List. - */ -void gdcmHeader::LoadHeaderEntries(void) { - rewind(fp); - for (ListTag::iterator i = GetPubListEntry().begin(); - i != GetPubListEntry().end(); - ++i){ - LoadHeaderEntry(*i); - } - - rewind(fp); - - // Load 'non string' values - std::string PhotometricInterpretation = GetPubEntryByNumber(0x0028,0x0004); - if( PhotometricInterpretation == "PALETTE COLOR " ){ - LoadEntryVoidArea(0x0028,0x1200); // gray LUT - LoadEntryVoidArea(0x0028,0x1201); // R LUT - LoadEntryVoidArea(0x0028,0x1202); // G LUT - LoadEntryVoidArea(0x0028,0x1203); // B LUT - - LoadEntryVoidArea(0x0028,0x1221); // Segmented Red Palette Color LUT Data - LoadEntryVoidArea(0x0028,0x1222); // Segmented Green Palette Color LUT Data - LoadEntryVoidArea(0x0028,0x1223); // Segmented Blue Palette Color LUT Data - } - - // -------------------------------------------------------------- - // Special Patch to allow gdcm to read ACR-LibIDO formated images - // - // if recognition code tells us we deal with a LibIDO image - // we switch lineNumber and columnNumber - // - std::string RecCode; - RecCode = GetPubEntryByNumber(0x0008, 0x0010); // recognition code - if (RecCode == "ACRNEMA_LIBIDO_1.1" || - RecCode == "CANRME_AILIBOD1_1." ) { - filetype = ACR_LIBIDO; - std::string rows = GetPubEntryByNumber(0x0028, 0x0010); - std::string columns = GetPubEntryByNumber(0x0028, 0x0011); - SetPubEntryByNumber(columns, 0x0028, 0x0010); - SetPubEntryByNumber(rows , 0x0028, 0x0011); - } - // ----------------- End of Special Patch ---------------- -} - -/** - * \ingroup gdcmHeader - * \brief Loads the element content if it's length is not bigger - * than the value specified with - * gdcmHeader::SetMaxSizeLoadElementValue() - * @param ElVal Header Entry (Dicom Element) to be dealt with - */ -void gdcmHeader::LoadHeaderEntry(gdcmHeaderEntry * ElVal) { - size_t item_read; - guint16 group = ElVal->GetGroup(); - std::string vr= ElVal->GetVR(); - guint32 length = ElVal->GetLength(); - bool SkipLoad = false; - - fseek(fp, (long)ElVal->GetOffset(), SEEK_SET); - - // the test was commented out to 'go inside' the SeQuences - // we don't any longer skip them ! - - // if( vr == "SQ" ) // (DO NOT remove this comment) - // SkipLoad = true; - - // A SeQuence "contains" a set of Elements. - // (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 ) - SkipLoad = true; - - if ( SkipLoad ) { - ElVal->SetLength(0); - ElVal->SetValue("gdcm::Skipped"); - return; - } - - // When the length is zero things are easy: - if ( length == 0 ) { - ElVal->SetValue(""); - return; - } - - // The elements whose length is bigger than the specified upper bound - // are not loaded. Instead we leave a short notice of the offset of - // the element content and it's length. - if (length > MaxSizeLoadElementValue) { - std::ostringstream s; - s << "gdcm::NotLoaded."; - s << " Address:" << (long)ElVal->GetOffset(); - s << " Length:" << ElVal->GetLength(); - s << " x(" << std::hex << ElVal->GetLength() << ")"; - ElVal->SetValue(s.str()); - return; - } - - // When integer(s) are expected, read and convert the following - // n *(two or four bytes) - // properly i.e. as integers as opposed to a strings. - // Elements with Value Multiplicity > 1 - // contain a set of integers (not a single one) - - // Any compacter code suggested (?) - if ( IsHeaderEntryAnInteger(ElVal) ) { - guint32 NewInt; - std::ostringstream s; - int nbInt; - if (vr == "US" || vr == "SS") { - nbInt = length / 2; - NewInt = ReadInt16(); - s << NewInt; - if (nbInt > 1) { - for (int i=1; i < nbInt; i++) { - s << '\\'; - NewInt = ReadInt16(); - s << NewInt; - } - } - - } else if (vr == "UL" || vr == "SL") { - nbInt = length / 4; - NewInt = ReadInt32(); - s << NewInt; - if (nbInt > 1) { - for (int i=1; i < nbInt; i++) { - s << '\\'; - NewInt = ReadInt32(); - s << NewInt; - } - } - } -#ifdef GDCM_NO_ANSI_STRING_STREAM - s << std::ends; // to avoid oddities on Solaris -#endif //GDCM_NO_ANSI_STRING_STREAM - ElVal->SetValue(s.str()); - return; - } - - // We need an additional byte for storing \0 that is not on disk - char* NewValue = (char*)malloc(length+1); - if( !NewValue) { - dbg.Verbose(1, "LoadElementValue: Failed to allocate NewValue"); - return; - } - NewValue[length]= 0; - - item_read = fread(NewValue, (size_t)length, (size_t)1, fp); - if ( item_read != 1 ) { - free(NewValue); - dbg.Verbose(1, "gdcmHeader::LoadElementValue","unread element value"); - ElVal->SetValue("gdcm::UnRead"); - return; - } - ElVal->SetValue(NewValue); - free(NewValue); -} - -/** - * \ingroup gdcmHeader - * \brief Loads the element while preserving the current - * underlying file position indicator as opposed to - * to LoadHeaderEntry that modifies it. - * @param entry Header Entry whose value shall be loaded. - * @return - */ -void gdcmHeader::LoadHeaderEntrySafe(gdcmHeaderEntry * entry) { - long PositionOnEntry = ftell(fp); - LoadHeaderEntry(entry); - fseek(fp, PositionOnEntry, SEEK_SET); -} - -/** - * \ingroup gdcmHeader - * \brief - * @param ElVal Header Entry whose length of the value shall be loaded. - - * @return - */ - void gdcmHeader::FindHeaderEntryLength (gdcmHeaderEntry * ElVal) { - guint16 element = ElVal->GetElement(); - guint16 group = ElVal->GetGroup(); - std::string vr = ElVal->GetVR(); - guint16 length16; - if( (element == 0x0010) && (group == 0x7fe0) ) { - dbg.SetDebug(-1); - dbg.Verbose(2, "gdcmHeader::FindLength: ", - "we reached 7fe0 0010"); - } - - if ( (filetype == ExplicitVR) && ! ElVal->IsImplicitVr() ) { - if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") ) { - - // The following reserved two bytes (see PS 3.5-2001, section - // 7.1.2 Data element structure with explicit vr p27) must be - // skipped before proceeding on reading the length on 4 bytes. - fseek(fp, 2L, SEEK_CUR); - - guint32 length32 = ReadInt32(); - - if ( (vr == "OB") && (length32 == 0xffffffff) ) { - ElVal->SetLength(FindHeaderEntryLengthOB()); - return; - } - FixHeaderEntryFoundLength(ElVal, length32); - return; - } - - // Length is encoded on 2 bytes. - length16 = ReadInt16(); - - // We can tell the current file is encoded in big endian (like - // Data/US-RGB-8-epicard) when we find the "Transfer Syntax" tag - // and it's value is the one of the encoding of a big endian file. - // In order to deal with such big endian encoded files, we have - // (at least) two strategies: - // * when we load the "Transfer Syntax" tag with value of big endian - // encoding, we raise the proper flags. Then we wait for the end - // of the META group (0x0002) among which is "Transfer Syntax", - // before switching the swap code to big endian. We have to postpone - // the switching of the swap code since the META group is fully encoded - // in little endian, and big endian coding only starts at the next - // group. The corresponding code can be hard to analyse and adds - // many additional unnecessary tests for regular tags. - // * the second strategy consists in waiting for trouble, that shall - // appear when we find the first group with big endian encoding. This - // is easy to detect since the length of a "Group Length" tag (the - // ones with zero as element number) has to be of 4 (0x0004). When we - // encounter 1024 (0x0400) chances are the encoding changed and we - // found a group with big endian encoding. - // We shall use this second strategy. In order to make sure that we - // can interpret the presence of an apparently big endian encoded - // length of a "Group Length" without committing a big mistake, we - // add an additional check: we look in the already parsed elements - // for the presence of a "Transfer Syntax" whose value has to be "big - // endian encoding". When this is the case, chances are we have got our - // hands on a big endian encoded file: we switch the swap code to - // big endian and proceed... - if ( (element == 0x0000) && (length16 == 0x0400) ) { - if ( ! IsExplicitVRBigEndianTransferSyntax() ) { - dbg.Verbose(0, "gdcmHeader::FindLength", "not explicit VR"); - errno = 1; - return; - } - length16 = 4; - SwitchSwapToBigEndian(); - // Restore the unproperly loaded values i.e. the group, the element - // and the dictionary entry depending on them. - guint16 CorrectGroup = SwapShort(ElVal->GetGroup()); - guint16 CorrectElem = SwapShort(ElVal->GetElement()); - gdcmDictEntry * NewTag = GetDictEntryByNumber(CorrectGroup, - CorrectElem); - if (!NewTag) { - // This correct tag is not in the dictionary. Create a new one. - NewTag = Dicts->NewVirtualDictEntry(CorrectGroup, CorrectElem); - } - // FIXME this can create a memory leaks on the old entry that be - // left unreferenced. - ElVal->SetDictEntry(NewTag); - } - - // Heuristic: well some files are really ill-formed. - if ( length16 == 0xffff) { - length16 = 0; - //dbg.Verbose(0, "gdcmHeader::FindLength", - // "Erroneous element length fixed."); - // Actually, length= 0xffff means that we deal with - // Unknown Sequence Length - } - - FixHeaderEntryFoundLength(ElVal, (guint32)length16); - return; - } - - // Either implicit VR or a non DICOM conformal (see not below) explicit - // VR that ommited the VR of (at least) this element. Farts happen. - // [Note: according to the part 5, PS 3.5-2001, section 7.1 p25 - // on Data elements "Implicit and Explicit VR Data Elements shall - // not coexist in a Data Set and Data Sets nested within it".] - // Length is on 4 bytes. - FixHeaderEntryFoundLength(ElVal, ReadInt32()); - return; -} - -/** - * \ingroup gdcmHeader - * \brief Find the Value Representation of the current Dicom Element. - * @param ElVal - */ -void gdcmHeader::FindHeaderEntryVR( gdcmHeaderEntry *ElVal) { - if (filetype != ExplicitVR) - return; - - char VR[3]; - std::string vr; - int lgrLue; - char msg[100]; // for sprintf. Sorry - - long PositionOnEntry = ftell(fp); - // Warning: we believe this is explicit VR (Value Representation) because - // we used a heuristic that found "UL" in the first tag. Alas this - // doesn't guarantee that all the tags will be in explicit VR. In some - // cases (see e-film filtered files) one finds implicit VR tags mixed - // within an explicit VR file. Hence we make sure the present tag - // is in explicit VR and try to fix things if it happens not to be - // the case. - bool RealExplicit = true; - - lgrLue=fread (&VR, (size_t)2,(size_t)1, fp); - VR[2]=0; - vr = std::string(VR); - - // Assume we are reading a falsely explicit VR file i.e. we reached - // a tag where we expect reading a VR but are in fact we read the - // first to bytes of the length. Then we will interogate (through find) - // the dicom_vr dictionary with oddities like "\004\0" which crashes - // both GCC and VC++ implementations of the STL map. Hence when the - // expected VR read happens to be non-ascii characters we consider - // we hit falsely explicit VR tag. - - if ( (!isalpha(VR[0])) && (!isalpha(VR[1])) ) - RealExplicit = false; - - // CLEANME searching the dicom_vr at each occurence is expensive. - // PostPone this test in an optional integrity check at the end - // of parsing or only in debug mode. - if ( RealExplicit && !dicom_vr->Count(vr) ) - RealExplicit= false; - - if ( RealExplicit ) { - if ( ElVal->IsVRUnknown() ) { - // When not a dictionary entry, we can safely overwrite the VR. - ElVal->SetVR(vr); - return; - } - if ( ElVal->GetVR() == vr ) { - // The VR we just read and the dictionary agree. Nothing to do. - return; - } - // The VR present in the file and the dictionary disagree. We assume - // the file writer knew best and use the VR of the file. Since it would - // be unwise to overwrite the VR of a dictionary (since it would - // compromise it's next user), we need to clone the actual DictEntry - // and change the VR for the read one. - gdcmDictEntry* NewTag = Dicts->NewVirtualDictEntry(ElVal->GetGroup(), - ElVal->GetElement(), - vr, - "FIXME", - ElVal->GetName()); - ElVal->SetDictEntry(NewTag); - return; - } - - // We thought this was explicit VR, but we end up with an - // implicit VR tag. Let's backtrack. - - sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", - ElVal->GetGroup(),ElVal->GetElement()); - dbg.Verbose(1, "gdcmHeader::FindVR: ",msg); - - fseek(fp, PositionOnEntry, SEEK_SET); - // When this element is known in the dictionary we shall use, e.g. for - // the semantics (see the usage of IsAnInteger), the VR proposed by the - // dictionary entry. Still we have to flag the element as implicit since - // we know now our assumption on expliciteness is not furfilled. - // avoid . - if ( ElVal->IsVRUnknown() ) - ElVal->SetVR("Implicit"); - ElVal->SetImplicitVr(); -} - -/** - * \ingroup gdcmHeader - * \brief Skip a given Header Entry - * \warning NOT end user intended method ! - * @param entry - * @return - */ -void gdcmHeader::SkipHeaderEntry(gdcmHeaderEntry * entry) { - SkipBytes(entry->GetLength()); -} - -/** - * \ingroup gdcmHeader - * \brief When the length of an element value is obviously wrong (because - * the parser went Jabberwocky) one can hope improving things by - * applying this heuristic. - */ -void gdcmHeader::FixHeaderEntryFoundLength(gdcmHeaderEntry * ElVal, guint32 FoundLength) { - - ElVal->SetReadLength(FoundLength); // will be updated only if a bug is found - - if ( FoundLength == 0xffffffff) { - FoundLength = 0; - } - - // Sorry for the patch! - // XMedCom did the trick to read some nasty GE images ... - else if (FoundLength == 13) { - // The following 'if' will be removed when there is no more - // images on Creatis HDs with a 13 length for Manufacturer... - if ( (ElVal->GetGroup() != 0x0008) || - ( (ElVal->GetElement() != 0x0070) && (ElVal->GetElement() != 0x0080) ) ) { - // end of remove area - FoundLength =10; - ElVal->SetReadLength(10); // a bug is to be fixed - } - } - // to fix some garbage 'Leonardo' Siemens images - // May be commented out to avoid overhead - else if ( (ElVal->GetGroup() == 0x0009) && - ( (ElVal->GetElement() == 0x1113) || (ElVal->GetElement() == 0x1114) ) ){ - FoundLength =4; - ElVal->SetReadLength(4); // a bug is to be fixed - } - // end of fix - - // to try to 'go inside' SeQuences (with length), and not to skip them - else if ( ElVal->GetVR() == "SQ") { - if (enableSequences) // only if the user does want to ! - FoundLength =0; - } - - // a SeQuence Element is beginning - // Let's forget it's length - // (we want to 'go inside') - - // Pb : *normaly* fffe|e000 is just a marker, its length *should be* zero - // in gdcm-MR-PHILIPS-16-Multi-Seq.dcm we find lengthes as big as 28800 - // if we set the length to zero IsHeaderEntryAnInteger() breaks... - // if we don't, we lost 28800 characters from the Header :-( - - else if(ElVal->GetGroup() == 0xfffe){ - // sometimes, length seems to be wrong - FoundLength =0; // some more clever checking to be done ! - // I give up! - // only gdcm-MR-PHILIPS-16-Multi-Seq.dcm - // causes troubles :-( - } - - ElVal->SetUsableLength(FoundLength); -} - -/** - * \ingroup gdcmHeader - * \brief Apply some heuristics to predict wether the considered - * element value contains/represents an integer or not. - * @param ElVal The element value on which to apply the predicate. - * @return The result of the heuristical predicate. - */ -bool gdcmHeader::IsHeaderEntryAnInteger(gdcmHeaderEntry * ElVal) { - guint16 element = ElVal->GetElement(); - guint16 group = ElVal->GetGroup(); - std::string vr = ElVal->GetVR(); - guint32 length = ElVal->GetLength(); - - // When we have some semantics on the element we just read, and if we - // a priori know we are dealing with an integer, then we shall be - // able to swap it's element value properly. - if ( element == 0 ) { // This is the group length of the group - if (length == 4) - return true; - else { - std::ostringstream s; - s << "Erroneous Group Length element length on :" \ - << std::hex << group << " , " << element; - dbg.Error("gdcmHeader::IsAnInteger", - s.str().c_str()); - } - } - if ( (vr == "UL") || (vr == "US") || (vr == "SL") || (vr == "SS") ) - return true; - - return false; -} - -/** - * \ingroup gdcmHeader - * \brief - * - * @return - */ - guint32 gdcmHeader::FindHeaderEntryLengthOB(void) { - // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data. - guint16 g; - guint16 n; - long PositionOnEntry = ftell(fp); - bool FoundSequenceDelimiter = false; - guint32 TotalLength = 0; - guint32 ItemLength; - - while ( ! FoundSequenceDelimiter) { - g = ReadInt16(); - n = ReadInt16(); - if (errno == 1) - return 0; - TotalLength += 4; // We even have to decount the group and element - - if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ { - char msg[100]; // for sprintf. Sorry - sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n); - dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg); - errno = 1; - return 0; - } - if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header */ - FoundSequenceDelimiter = true; - else if ( n != 0xe000 ){ - char msg[100]; // for sprintf. Sorry - sprintf(msg,"wrong element (%04x) for an item sequence (%04x,%04x)\n", - n, g,n); - dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg); - errno = 1; - return 0; - } - ItemLength = ReadInt32(); - TotalLength += ItemLength + 4; // We add 4 bytes since we just read - // the ItemLength with ReadInt32 - SkipBytes(ItemLength); - } - fseek(fp, PositionOnEntry, SEEK_SET); - return TotalLength; -} - -/** - * \ingroup gdcmHeader - * \brief Reads a supposed to be 16 Bits integer - * \ (swaps it depending on processor endianity) - * - * @return integer acts as a boolean - */ -guint16 gdcmHeader::ReadInt16(void) { - guint16 g; - size_t item_read; - item_read = fread (&g, (size_t)2,(size_t)1, fp); - if ( item_read != 1 ) { - // dbg.Verbose(0, "gdcmHeader::ReadInt16", " Failed to read :"); - // if(feof(fp)) - // dbg.Verbose(0, "gdcmHeader::ReadInt16", " End of File encountered"); - if(ferror(fp)) - dbg.Verbose(0, "gdcmHeader::ReadInt16", " File Error"); - errno = 1; - return 0; - } - errno = 0; - g = SwapShort(g); - return g; -} - -/** - * \ingroup gdcmHeader - * \brief Reads a supposed to be 32 Bits integer - * \ (swaps it depending on processor endianity) - * - * @return - */ -guint32 gdcmHeader::ReadInt32(void) { - guint32 g; - size_t item_read; - item_read = fread (&g, (size_t)4,(size_t)1, fp); - if ( item_read != 1 ) { - //dbg.Verbose(0, "gdcmHeader::ReadInt32", " Failed to read :"); - //if(feof(fp)) - // dbg.Verbose(0, "gdcmHeader::ReadInt32", " End of File encountered"); - if(ferror(fp)) - dbg.Verbose(0, "gdcmHeader::ReadInt32", " File Error"); - errno = 1; - return 0; - } - errno = 0; - g = SwapLong(g); - return g; -} - -/** - * \ingroup gdcmHeader - * \brief - * - * @return - */ -void gdcmHeader::SkipBytes(guint32 NBytes) { - //FIXME don't dump the returned value - (void)fseek(fp, (long)NBytes, SEEK_CUR); -} - -/** - * \ingroup gdcmHeader - * \brief - */ -void gdcmHeader::Initialise(void) { - dicom_vr = gdcmGlobal::GetVR(); - dicom_ts = gdcmGlobal::GetTS(); - Dicts = gdcmGlobal::GetDicts(); - RefPubDict = Dicts->GetDefaultPubDict(); - RefShaDict = (gdcmDict*)0; -} - -/** - * \ingroup gdcmHeader - * \brief Discover what the swap code is (among little endian, big endian, - * bad little endian, bad big endian). - * - */ -void gdcmHeader::CheckSwap() -{ - // Fourth semantics: - // - // ---> Warning : This fourth field is NOT part - // of the 'official' Dicom Dictionnary - // and should NOT be used. - // (Not defined for all the groups - // may be removed in a future release) - // - // CMD Command - // META Meta Information - // DIR Directory - // ID - // PAT Patient - // ACQ Acquisition - // REL Related - // IMG Image - // SDY Study - // VIS Visit - // WAV Waveform - // PRC - // DEV Device - // NMI Nuclear Medicine - // MED - // BFS Basic Film Session - // BFB Basic Film Box - // BIB Basic Image Box - // BAB - // IOB - // PJ - // PRINTER - // RT Radio Therapy - // DVH - // SSET - // RES Results - // CRV Curve - // OLY Overlays - // PXL Pixels - // DL Delimiters - // - - // 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... - guint32 s; - guint32 x=4; // x : for ntohs - bool net2host; // true when HostByteOrder is the same as NetworkByteOrder - - int lgrLue; - char * entCur; - char deb[HEADER_LENGTH_TO_READ]; - - // First, compare HostByteOrder and NetworkByteOrder in order to - // determine if we shall need to swap bytes (i.e. the Endian type). - if (x==ntohs(x)) - net2host = true; - else - net2host = false; - //cout << net2host << endl; - - // The easiest case is the one of a DICOM header, since it possesses a - // file preamble where it suffice to look for the string "DICM". - lgrLue = fread(deb, 1, HEADER_LENGTH_TO_READ, fp); - - entCur = deb + 128; - if(memcmp(entCur, "DICM", (size_t)4) == 0) { - dbg.Verbose(1, "gdcmHeader::CheckSwap:", "looks like DICOM Version3"); - // Next, determine the value representation (VR). Let's skip to the - // first element (0002, 0000) and check there if we find "UL" - // - or "OB" if the 1st one is (0002,0001) -, - // in which case we (almost) know it is explicit VR. - // WARNING: if it happens to be implicit VR then what we will read - // is the length of the group. If this ascii representation of this - // length happens to be "UL" then we shall believe it is explicit VR. - // FIXME: in order to fix the above warning, we could read the next - // element value (or a couple of elements values) in order to make - // sure we are not commiting a big mistake. - // We need to skip : - // * the 128 bytes of File Preamble (often padded with zeroes), - // * the 4 bytes of "DICM" string, - // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001) - // i.e. a total of 136 bytes. - entCur = deb + 136; - // FIXME - // Use gdcmHeader::dicom_vr to test all the possibilities - // instead of just checking for UL, OB and UI !? - if( (memcmp(entCur, "UL", (size_t)2) == 0) || - (memcmp(entCur, "OB", (size_t)2) == 0) || - (memcmp(entCur, "UI", (size_t)2) == 0) ) - { - filetype = ExplicitVR; - dbg.Verbose(1, "gdcmHeader::CheckSwap:", - "explicit Value Representation"); - } else { - filetype = ImplicitVR; - dbg.Verbose(1, "gdcmHeader::CheckSwap:", - "not an explicit Value Representation"); - } - if (net2host) { - sw = 4321; - dbg.Verbose(1, "gdcmHeader::CheckSwap:", - "HostByteOrder != NetworkByteOrder"); - } else { - sw = 0; - dbg.Verbose(1, "gdcmHeader::CheckSwap:", - "HostByteOrder = NetworkByteOrder"); - } - - // Position the file position indicator at first tag (i.e. - // after the file preamble and the "DICM" string). - rewind(fp); - fseek (fp, 132L, SEEK_SET); - return; - } // End of DicomV3 - - // Alas, this is not a DicomV3 file and whatever happens there is no file - // preamble. We can reset the file position indicator to where the data - // is (i.e. the beginning of the file). - dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not a DICOM Version3 file"); - rewind(fp); - - // Our next best chance would be to be considering a 'clean' ACR/NEMA file. - // By clean we mean that the length of the first tag is written down. - // If this is the case and since the length of the first group HAS to be - // four (bytes), then determining the proper swap code is straightforward. - - entCur = deb + 4; - // We assume the array of char we are considering contains the binary - // representation of a 32 bits integer. Hence the following dirty - // trick : - s = *((guint32 *)(entCur)); - - switch (s) { - case 0x00040000 : - sw = 3412; - filetype = ACR; - return; - case 0x04000000 : - sw = 4321; - filetype = ACR; - return; - case 0x00000400 : - sw = 2143; - filetype = ACR; - return; - case 0x00000004 : - sw = 0; - filetype = ACR; - return; - default : - dbg.Verbose(0, "gdcmHeader::CheckSwap:", - "ACR/NEMA unfound swap info (time to raise bets)"); - } - - // We are out of luck. It is not a DicomV3 nor a 'clean' ACR/NEMA file. - // It is time for despaired wild guesses. So, let's assume this file - // happens to be 'dirty' ACR/NEMA, i.e. the length of the group is - // not present. Then the only info we have is the net2host one. - filetype = Unknown; - if (! net2host ) - sw = 0; - else - sw = 4321; - return; -} - -/** - * \ingroup gdcmHeader - * \brief - */ -void gdcmHeader::SwitchSwapToBigEndian(void) { - dbg.Verbose(1, "gdcmHeader::SwitchSwapToBigEndian", - "Switching to BigEndian mode."); - if ( sw == 0 ) { - sw = 4321; - return; - } - if ( sw == 4321 ) { - sw = 0; - return; - } - if ( sw == 3412 ) { - sw = 2143; - return; - } - if ( sw == 2143 ) - sw = 3412; -} - -/** - * \ingroup gdcmHeader - * \brief - * @param NewSize - * @return - */ -void gdcmHeader::SetMaxSizeLoadElementValue(long NewSize) { - if (NewSize < 0) - return; - if ((guint32)NewSize >= (guint32)0xffffffff) { - MaxSizeLoadElementValue = 0xffffffff; - return; - } - MaxSizeLoadElementValue = NewSize; -} - -/** - * \ingroup gdcmHeader - * \brief Searches both the public and the shadow dictionary (when they - * exist) for the presence of the DictEntry with given - * group and element. The public dictionary has precedence on the - * shadow one. - * @param group group of the searched DictEntry - * @param element element of the searched DictEntry - * @return Corresponding DictEntry when it exists, NULL otherwise. - */ -gdcmDictEntry * gdcmHeader::GetDictEntryByNumber(guint16 group, - guint16 element) { - gdcmDictEntry * found = (gdcmDictEntry*)0; - if (!RefPubDict && !RefShaDict) { - dbg.Verbose(0, "gdcmHeader::GetDictEntry", - "we SHOULD have a default dictionary"); - } - if (RefPubDict) { - found = RefPubDict->GetTagByNumber(group, element); - if (found) - return found; - } - if (RefShaDict) { - found = RefShaDict->GetTagByNumber(group, element); - if (found) - return found; - } - return found; -} - -/** - * \ingroup gdcmHeader - * \brief Searches both the public and the shadow dictionary (when they - * exist) for the presence of the DictEntry with given name. - * The public dictionary has precedence on the shadow one. - * @param Name name of the searched DictEntry - * @return Corresponding DictEntry when it exists, NULL otherwise. - */ -gdcmDictEntry * gdcmHeader::GetDictEntryByName(std::string Name) { - gdcmDictEntry * found = (gdcmDictEntry*)0; - if (!RefPubDict && !RefShaDict) { - dbg.Verbose(0, "gdcmHeader::GetDictEntry", - "we SHOULD have a default dictionary"); - } - if (RefPubDict) { - found = RefPubDict->GetTagByName(Name); - if (found) - return found; - } - if (RefShaDict) { - found = RefShaDict->GetTagByName(Name); - if (found) - return found; - } - return found; -} - -/** - * \ingroup gdcmHeader - * \brief Read the next tag but WITHOUT loading it's value - * @return On succes the newly created HeaderEntry, NULL on failure. - */ -gdcmHeaderEntry * gdcmHeader::ReadNextHeaderEntry(void) { - - guint16 g,n; - gdcmHeaderEntry * NewElVal; - - g = ReadInt16(); - n = ReadInt16(); - - if (errno == 1) - // We reached the EOF (or an error occured) and header parsing - // has to be considered as finished. - return (gdcmHeaderEntry *)0; - - NewElVal = NewHeaderEntryByNumber(g, n); - FindHeaderEntryVR(NewElVal); - FindHeaderEntryLength(NewElVal); - - if (errno == 1) { - // Call it quits - return (gdcmHeaderEntry *)0; - } - NewElVal->SetOffset(ftell(fp)); - //if ( (g==0x7fe0) && (n==0x0010) ) - return NewElVal; -} - -/** - * \ingroup gdcmHeader - * \brief Build a new Element Value from all the low level arguments. - * Check for existence of dictionary entry, and build - * a default one when absent. - * @param Name Name of the underlying DictEntry - */ -gdcmHeaderEntry* gdcmHeader::NewHeaderEntryByName(std::string Name) { - - gdcmDictEntry * NewTag = GetDictEntryByName(Name); - if (!NewTag) - NewTag = Dicts->NewVirtualDictEntry(0xffff, 0xffff, "LO", "Unknown", Name); - - gdcmHeaderEntry* NewElVal = new gdcmHeaderEntry(NewTag); - if (!NewElVal) { - dbg.Verbose(1, "gdcmHeader::ObtainHeaderEntryByName", - "failed to allocate gdcmHeaderEntry"); - return (gdcmHeaderEntry*)0; - } - return NewElVal; -} - -/** - * \ingroup gdcmHeader - * \brief Build a new Element Value from all the low level arguments. - * Check for existence of dictionary entry, and build - * a default one when absent. - * @param Group group of the underlying DictEntry - * @param Elem element of the underlying DictEntry - */ -gdcmHeaderEntry* gdcmHeader::NewHeaderEntryByNumber(guint16 Group, guint16 Elem) { - // Find out if the tag we encountered is in the dictionaries: - gdcmDictEntry * NewTag = GetDictEntryByNumber(Group, Elem); - if (!NewTag) - NewTag = Dicts->NewVirtualDictEntry(Group, Elem); - - gdcmHeaderEntry* NewElVal = new gdcmHeaderEntry(NewTag); - if (!NewElVal) { - dbg.Verbose(1, "gdcmHeader::NewHeaderEntryByNumber", - "failed to allocate gdcmHeaderEntry"); - return (gdcmHeaderEntry*)0; - } - return NewElVal; -} - -/** - * \ingroup gdcmHeader - * \brief Small utility function that creates a new manually crafted - * (as opposed as read from the file) gdcmHeaderEntry with user - * specified name and adds it to the public tag hash table. - * \note A fake TagKey is generated so the PubDict can keep it's coherence. - * @param NewTagName The name to be given to this new tag. - * @param VR The Value Representation to be given to this new tag. - * @return The newly hand crafted Element Value. - */ -gdcmHeaderEntry* gdcmHeader::NewManualHeaderEntryToPubDict(std::string NewTagName, - std::string VR) { - gdcmHeaderEntry* NewElVal = (gdcmHeaderEntry*)0; - guint32 StuffGroup = 0xffff; // Group to be stuffed with additional info - guint32 FreeElem = 0; - gdcmDictEntry* NewEntry = (gdcmDictEntry*)0; - - FreeElem = GenerateFreeTagKeyInGroup(StuffGroup); - if (FreeElem == UINT32_MAX) { - dbg.Verbose(1, "gdcmHeader::NewManualElValToPubDict", - "Group 0xffff in Public Dict is full"); - return (gdcmHeaderEntry*)0; - } - NewEntry = Dicts->NewVirtualDictEntry(StuffGroup, FreeElem, - VR, "GDCM", NewTagName); - NewElVal = new gdcmHeaderEntry(NewEntry); - Add(NewElVal); - return NewElVal; -} //----------------------------------------------------------------------------- diff --git a/src/gdcmHeader.h b/src/gdcmHeader.h index a5828675..1ddff5a0 100644 --- a/src/gdcmHeader.h +++ b/src/gdcmHeader.h @@ -4,31 +4,7 @@ #define GDCMHEADER_H #include "gdcmCommon.h" -#include "gdcmVR.h" -#include "gdcmTS.h" -#include "gdcmException.h" -#include "gdcmDictSet.h" -#include "gdcmHeaderEntry.h" - -#include -#include -#include // for linking together *all* the Dicom Elements - -//----------------------------------------------------------------------------- -typedef std::string VRKey; -typedef std::string VRAtr; -typedef std::map VRHT; // Value Representation Hash Table - -typedef std::multimap TagHeaderEntryHT; -typedef std::pair PairHT; -typedef std::pair IterHT; - -typedef std::list ListTag; // for linking together the Elements - -// TODO : to be removed after re-writting gdcmHeaderEntrySet::UpdateGroupLength -// using the chained list instead of the H table -typedef std::string GroupKey; -typedef std::map GroupHT; +#include "gdcmParser.h" //----------------------------------------------------------------------------- /* @@ -51,7 +27,8 @@ typedef std::map GroupHT; * protected due to Swig limitations for as Has_a dependency between * gdcmFile and gdcmHeader. */ -class GDCM_EXPORT gdcmHeader { +class GDCM_EXPORT gdcmHeader : public gdcmParser +{ public: gdcmHeader(bool exception_on_error = false); gdcmHeader(const char *filename, @@ -61,13 +38,6 @@ public: virtual ~gdcmHeader(); // Standard values and informations contained in the header - inline std::string GetFileName(void) {return filename;} - - bool IsReadable(void); - bool IsImplicitVRLittleEndianTransferSyntax(void); - bool IsExplicitVRLittleEndianTransferSyntax(void); - bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void); - bool IsExplicitVRBigEndianTransferSyntax(void); bool IsJPEGBaseLineProcess1TransferSyntax(void); bool IsJPEGExtendedProcess2_4TransferSyntax(void); bool IsJPEGExtendedProcess3_5TransferSyntax(void); @@ -76,7 +46,6 @@ public: bool IsJPEGLossless(void); bool IsJPEG2000(void); bool IsDicomV3(void); - FileType GetFileType(void); // Some heuristic based accessors, end user intended // (to be move to gdcmHeaderHelper?) @@ -109,189 +78,30 @@ public: // TODO Swig int SetShaDict(std::string filename); // TODO Swig int SetPubDict(std::string filename); -// Public element value - std::string GetPubEntryByName (std::string tagName); - std::string GetPubEntryVRByName (std::string tagName); - std::string GetPubEntryByNumber (guint16 group, guint16 element); - std::string GetPubEntryVRByNumber(guint16 group, guint16 element); - - bool SetPubEntryByName (std::string content, std::string tagName); - bool SetPubEntryByNumber(std::string content, guint16 group, guint16 element); - bool SetPubEntryLengthByNumber(guint32 lgr, guint16 group, guint16 element); - - /** - * \ingroup gdcmHeader - * \brief returns a ref to the Dicom Header H table (multimap) - * return the Dicom Header H table - */ - inline TagHeaderEntryHT & GetPubEntry(void) { return tagHT; }; - - /** - * \ingroup gdcmHeader - * \brief returns a ref to the Dicom Header chained list - * return the Dicom Header chained list - */ - inline ListTag & GetPubListEntry(void) { return listEntries; }; - - /** - * \ingroup gdcmHeader - * \brief Sets the print level for the Dicom Header - * \note 0 for Light Print; 1 for 'medium' Print, 2 for Heavy - */ - void SetPrintLevel(int level) { printLevel = level; }; - - void PrintPubEntry(std::ostream & os = std::cout); - void PrintPubDict (std::ostream & os = std::cout); - -// Element value - std::string GetEntryByName (std::string tagName); - std::string GetEntryVRByName (std::string tagName); - std::string GetEntryByNumber (guint16 group, guint16 element); - std::string GetEntryVRByNumber(guint16 group, guint16 element); +// Entry + inline virtual std::string GetEntryByName (std::string tagName) + { return(gdcmParser::GetEntryByName(tagName)); } + inline virtual std::string GetEntryVRByName (std::string tagName) + { return(gdcmParser::GetEntryVRByName(tagName)); } + inline virtual std::string GetEntryByNumber (guint16 group, guint16 element) + { return(gdcmParser::GetEntryByNumber(group,element)); } + inline virtual std::string GetEntryVRByNumber(guint16 group, guint16 element) + { return(gdcmParser::GetEntryVRByNumber(group,element)); } - bool SetEntryByName(std::string content,std::string tagName); -// bool SetEntryByNumber(std::string content,guint16 group, guint16 element); + inline virtual bool SetEntryByName(std::string content,std::string tagName) + { return(gdcmParser::SetEntryByName(content,tagName)); } + inline virtual bool SetEntryByNumber(std::string content,guint16 group, guint16 element) + { return(gdcmParser::SetEntryByNumber(content,group,element)); } // Read (used in gdcmFile) - FILE *OpenFile(bool exception_on_error = false) throw(gdcmFileError); - bool CloseFile(void); - virtual void ParseHeader(bool exception_on_error = false) throw(gdcmFormatError); - -// Write (used in gdcmFile) - bool Write(FILE *, FileType); void SetImageDataSize(size_t ExpectedSize); - bool ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem); - bool ReplaceOrCreateByNumber( char * Value, guint16 Group, guint16 Elem); - bool ReplaceIfExistByNumber ( char * Value, guint16 Group, guint16 Elem); - -// System access - inline int GetSwapCode(void) { return sw; } - guint16 SwapShort(guint16); // needed by gdcmFile - guint32 SwapLong(guint32); // for JPEG Files - - - -// ================= Was in EntrySet ================= - void Print(std::ostream & os = std::cout); - void Add(gdcmHeaderEntry*); - bool SetEntryByNumber(std::string content, guint16 group, guint16 element); - bool SetEntryLengthByNumber(guint32 l, guint16 group, guint16 element); - bool SetVoidAreaByNumber(void *a, guint16 Group, guint16 Elem ); - guint32 GenerateFreeTagKeyInGroup(guint16 group); -// =================================================== - - protected: - int CheckIfExistByNumber(guint16 Group, guint16 Elem ); // int ! - - gdcmHeaderEntry *GetHeaderEntryByName (std::string Name); - gdcmHeaderEntry *GetHeaderEntryByNumber(guint16 group, guint16 element); - int write(std::ostream&); int anonymize(std::ostream&); // FIXME : anonymize should be a friend ? - size_t GetPubEntryOffsetByNumber (guint16 Group, guint16 Elem); - void * GetPubEntryVoidAreaByNumber(guint16 Group, guint16 Elem); - void * LoadEntryVoidArea (guint16 Group, guint16 Element); - - -// ================= Was in EntrySet ================= - void UpdateGroupLength(bool SkipSequence = false, FileType type = ImplicitVR); - void WriteEntries(FileType type, FILE *); -// =================================================== - -// Variables - FILE * fp; - FileType filetype; // ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown - private: - // Read - void LoadHeaderEntries (void); - void LoadHeaderEntry (gdcmHeaderEntry *); - void LoadHeaderEntrySafe (gdcmHeaderEntry *); - void FindHeaderEntryLength(gdcmHeaderEntry *); - void FindHeaderEntryVR (gdcmHeaderEntry *); - - void SkipHeaderEntry (gdcmHeaderEntry *); - void FixHeaderEntryFoundLength(gdcmHeaderEntry *, guint32); - bool IsHeaderEntryAnInteger (gdcmHeaderEntry *); - - guint32 FindHeaderEntryLengthOB(void); - - guint16 ReadInt16(void); - guint32 ReadInt32(void); - void SkipBytes(guint32); - - void Initialise(void); - void CheckSwap(void); - void SwitchSwapToBigEndian(void); - void SetMaxSizeLoadElementValue(long); - - // Dict - gdcmDictEntry *GetDictEntryByName (std::string Name); - gdcmDictEntry *GetDictEntryByNumber(guint16, guint16); - - // HeaderEntry related utilities - gdcmHeaderEntry *ReadNextHeaderEntry (void); - gdcmHeaderEntry *NewHeaderEntryByNumber(guint16 group, guint16 element); - gdcmHeaderEntry *NewHeaderEntryByName (std::string Name); - - // Deprecated (Not used) - gdcmHeaderEntry *NewManualHeaderEntryToPubDict(std::string NewTagName, - std::string VR); - -// Variables - // Pointer to the Value Representation Hash Table which contains all - // the VR of the DICOM version3 public dictionary. - gdcmVR *dicom_vr; // Not a class member for thread-safety reasons - - // Pointer to the Transfert Syntax Hash Table which contains all - // the TS of the DICOM version3 public dictionary. - gdcmTS *dicom_ts; // Not a class member for thread-safety reasons - - // Pointer to global dictionary container - gdcmDictSet *Dicts; // Not a class member for thread-safety reasons - - // Public dictionary used to parse this header - gdcmDict *RefPubDict; - - // Optional "shadow dictionary" (private elements) used to parse this - // header - gdcmDict *RefShaDict; - - - // ================ Was in gdcmHeaderEntrySet ========= - TagHeaderEntryHT tagHT; // H Table (multimap), to provide fast access - ListTag listEntries; // chained list, to keep the 'spacial' ordering - int wasUpdated; // true if a gdcmHeaderEntry was added post parsing - int printLevel; // for PrintHeader - // ==================================================== - - // Refering underlying filename. - std::string filename; - - int enableSequences; - - // FIXME sw should be an enum e.g. - //enum EndianType { - //LittleEndian, - //BadLittleEndian, - //BigEndian, - //BadBigEndian}; - // Swap code e.g. little, big, bad-big, bad-little endian). Warning: - // this code is not fixed during header parsing. - int sw; - - // Size treshold above which an element value will NOT be loaded in - // memory (to avoid loading the image/volume itself). By default, - // this upper bound is fixed to 1024 bytes (which might look reasonable - // when one considers the definition of the various VR contents). - guint32 MaxSizeLoadElementValue; - - static const unsigned int HEADER_LENGTH_TO_READ; - static const unsigned int MAX_SIZE_LOAD_ELEMENT_VALUE; }; //----------------------------------------------------------------------------- diff --git a/src/gdcmHeader2.cxx b/src/gdcmHeader2.cxx index 263e2608..ce9d2159 100644 --- a/src/gdcmHeader2.cxx +++ b/src/gdcmHeader2.cxx @@ -20,7 +20,7 @@ * using both H table and Chained List * @param os The output stream to be written to. */ -void gdcmHeader::Print(std::ostream & os) { +/*void gdcmHeader::Print(std::ostream & os) { size_t o; unsigned short int g, e; @@ -55,7 +55,7 @@ void gdcmHeader::Print(std::ostream & os) { * \ when position to be taken care of * @param newHeaderEntry */ -void gdcmHeader::Add(gdcmHeaderEntry * newHeaderEntry) { +/*void gdcmHeader::Add(gdcmHeaderEntry * newHeaderEntry) { // tagHT [newHeaderEntry->GetKey()] = newHeaderEntry; tagHT.insert( PairHT( newHeaderEntry->GetKey(),newHeaderEntry) ); @@ -72,7 +72,7 @@ void gdcmHeader::Add(gdcmHeaderEntry * newHeaderEntry) { * @param element Element number of the searched Dicom Element * @return */ -bool gdcmHeader::SetVoidAreaByNumber(void * area, +/*bool gdcmHeader::SetVoidAreaByNumber(void * area, guint16 group, guint16 element) { TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHT.count(key)) @@ -89,7 +89,7 @@ bool gdcmHeader::SetVoidAreaByNumber(void * area, * @param group The generated tag must belong to this group. * @return The element of tag with given group which is fee. */ -guint32 gdcmHeader::GenerateFreeTagKeyInGroup(guint16 group) { +/*guint32 gdcmHeader::GenerateFreeTagKeyInGroup(guint16 group) { for (guint32 elem = 0; elem < UINT32_MAX; elem++) { TagKey key = gdcmDictEntry::TranslateToKey(group, elem); if (tagHT.count(key) == 0) @@ -112,7 +112,7 @@ guint32 gdcmHeader::GenerateFreeTagKeyInGroup(guint16 group) { * @param SkipSequence TRUE if we don't want to write Sequences (ACR-NEMA Files) * @param type Type of the File (ExplicitVR,ImplicitVR, ACR, ...) */ -void gdcmHeader::UpdateGroupLength(bool SkipSequence, FileType type) { +/*void gdcmHeader::UpdateGroupLength(bool SkipSequence, FileType type) { guint16 gr, el; std::string vr; @@ -208,7 +208,7 @@ void gdcmHeader::UpdateGroupLength(bool SkipSequence, FileType type) { * (ACR-NEMA, ExplicitVR, ImplicitVR) * @param _fp already open file pointer */ -void gdcmHeader::WriteEntries(FileType type, FILE * _fp) { +/*void gdcmHeader::WriteEntries(FileType type, FILE * _fp) { guint16 gr, el; guint32 lgr; const char * val; @@ -294,5 +294,5 @@ void gdcmHeader::WriteEntries(FileType type, FILE * _fp) { fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); // Elem value } } - +*/ //----------------------------------------------------------------------------- diff --git a/src/gdcmHeaderEntry.h b/src/gdcmHeaderEntry.h index be3f4f85..f414704c 100644 --- a/src/gdcmHeaderEntry.h +++ b/src/gdcmHeaderEntry.h @@ -3,11 +3,12 @@ #ifndef GDCMHeaderEntry_H #define GDCMHeaderEntry_H +#include +#include + #include "gdcmDictEntry.h" class gdcmHeader; -#include - //----------------------------------------------------------------------------- /* * The dicom header of a Dicom file contains a set of such entries diff --git a/src/gdcmHeaderHelper.cxx b/src/gdcmHeaderHelper.cxx index abfdf381..aeb83222 100644 --- a/src/gdcmHeaderHelper.cxx +++ b/src/gdcmHeaderHelper.cxx @@ -88,7 +88,7 @@ int gdcmHeaderHelper::GetPixelSize() { // 0028 0100 US IMG Bits Allocated // (in order no to be messed up by old RGB images) - if (gdcmHeader::GetPubEntryByNumber(0x0028,0x0100) == "24") + if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24") return 3; std::string PixelType = GetPixelType(); @@ -118,7 +118,7 @@ int gdcmHeaderHelper::GetPixelSize() { */ std::string gdcmHeaderHelper::GetPixelType() { std::string BitsAlloc; - BitsAlloc = GetPubEntryByNumber(0x0028, 0x0100); + BitsAlloc = GetEntryByNumber(0x0028, 0x0100); if (BitsAlloc == GDCM_UNFOUND) { // Bits Allocated dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated"); BitsAlloc = std::string("16"); @@ -129,7 +129,7 @@ std::string gdcmHeaderHelper::GetPixelType() { BitsAlloc = std::string("8"); // by old RGB images) std::string Signed; - Signed = GetPubEntryByNumber(0x0028, 0x0103); + Signed = GetEntryByNumber(0x0028, 0x0103); if (Signed == GDCM_UNFOUND) { // "Pixel Representation" dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation"); BitsAlloc = std::string("0"); @@ -150,7 +150,7 @@ std::string gdcmHeaderHelper::GetPixelType() { */ float gdcmHeaderHelper::GetXSpacing() { float xspacing, yspacing; - std::string StrSpacing = GetPubEntryByNumber(0x0028,0x0030); + std::string StrSpacing = GetEntryByNumber(0x0028,0x0030); if (StrSpacing == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetXSpacing: unfound Pixel Spacing (0028,0030)"); @@ -174,7 +174,7 @@ float gdcmHeaderHelper::GetXSpacing() { */ float gdcmHeaderHelper::GetYSpacing() { float xspacing, yspacing; - std::string StrSpacing = GetPubEntryByNumber(0x0028,0x0030); + std::string StrSpacing = GetEntryByNumber(0x0028,0x0030); if (StrSpacing == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)"); @@ -208,11 +208,11 @@ float gdcmHeaderHelper::GetZSpacing() { // Si le Spacing Between Slices est absent, // on suppose que les coupes sont jointives - std::string StrSpacingBSlices = GetPubEntryByNumber(0x0018,0x0088); + std::string StrSpacingBSlices = GetEntryByNumber(0x0018,0x0088); if (StrSpacingBSlices == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices"); - std::string StrSliceThickness = GetPubEntryByNumber(0x0018,0x0050); + std::string StrSliceThickness = GetEntryByNumber(0x0018,0x0050); if (StrSliceThickness == GDCM_UNFOUND) return 1.; else @@ -229,7 +229,7 @@ float gdcmHeaderHelper::GetZSpacing() { float gdcmHeaderHelper::GetRescaleIntercept() { float resInter = 0.; - std::string StrRescInter = GetPubEntryByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept + std::string StrRescInter = GetEntryByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept if (StrRescInter != GDCM_UNFOUND) { if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) { dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty"); @@ -242,7 +242,7 @@ float gdcmHeaderHelper::GetRescaleIntercept() float gdcmHeaderHelper::GetRescaleSlope() { float resSlope = 1.; - std::string StrRescSlope = GetPubEntryByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope + std::string StrRescSlope = GetEntryByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope if (StrRescSlope != GDCM_UNFOUND) { if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) { dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty"); @@ -267,11 +267,11 @@ int gdcmHeaderHelper::GetNumberOfScalarComponents() { // 0028 0100 US IMG Bits Allocated // (in order no to be messed up by old RGB images) - if (gdcmHeader::GetPubEntryByNumber(0x0028,0x0100) == "24") + if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24") return 3; std::string PhotometricInterpretation = - gdcmHeader::GetPubEntryByNumber(0x0028,0x0004); + gdcmHeader::GetEntryByNumber(0x0028,0x0004); if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) { if (HasLUT()) // PALETTE COLOR is NOT enough @@ -305,7 +305,7 @@ int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() { // 0028 0100 US IMG Bits Allocated // (in order no to be messed up by old RGB images) - if (gdcmHeader::GetPubEntryByNumber(0x0028,0x0100) == "24") + if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24") return 3; // we assume that *all* kinds of YBR are dealt with @@ -314,22 +314,22 @@ int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() { std::string gdcmHeaderHelper::GetStudyUID() { - return GetPubEntryByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID + return GetEntryByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID } std::string gdcmHeaderHelper::GetSeriesUID() { - return GetPubEntryByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID + return GetEntryByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID } std::string gdcmHeaderHelper::GetClassUID() { - return GetPubEntryByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID + return GetEntryByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID } std::string gdcmHeaderHelper::GetInstanceUID() { - return GetPubEntryByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID + return GetEntryByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID } // Image Position Patient (0020,0032): @@ -350,11 +350,11 @@ std::string gdcmHeaderHelper::GetInstanceUID() */ float gdcmHeaderHelper::GetXOrigin() { float xImPos, yImPos, zImPos; - std::string StrImPos = GetPubEntryByNumber(0x0020,0x0032); + std::string StrImPos = GetEntryByNumber(0x0020,0x0032); if (StrImPos == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)"); - StrImPos = GetPubEntryByNumber(0x0020,0x0030); // For ACR-NEMA images + StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images if (StrImPos == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position (RET) (0020,0030)"); // How to tell the caller nothing was found ? @@ -375,11 +375,11 @@ float gdcmHeaderHelper::GetXOrigin() { */ float gdcmHeaderHelper::GetYOrigin() { float xImPos, yImPos, zImPos; - std::string StrImPos = GetPubEntryByNumber(0x0020,0x0032); + std::string StrImPos = GetEntryByNumber(0x0020,0x0032); if (StrImPos == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)"); - StrImPos = GetPubEntryByNumber(0x0020,0x0030); // For ACR-NEMA images + StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images if (StrImPos == GDCM_UNFOUND) { dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position (RET) (0020,0030)"); // How to tell the caller nothing was found ? @@ -402,7 +402,7 @@ float gdcmHeaderHelper::GetYOrigin() { */ float gdcmHeaderHelper::GetZOrigin() { float xImPos, yImPos, zImPos; - std::string StrImPos = GetPubEntryByNumber(0x0020,0x0032); + std::string StrImPos = GetEntryByNumber(0x0020,0x0032); if (StrImPos != GDCM_UNFOUND) { if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) { dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position Patient (0020,0032)"); @@ -411,7 +411,7 @@ float gdcmHeaderHelper::GetZOrigin() { return zImPos; } } - StrImPos = GetPubEntryByNumber(0x0020,0x0030); // For ACR-NEMA images + StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images if (StrImPos != GDCM_UNFOUND) { if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) { dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position (RET) (0020,0030)"); @@ -420,7 +420,7 @@ float gdcmHeaderHelper::GetZOrigin() { return zImPos; } } - std::string StrSliceLocation = GetPubEntryByNumber(0x0020,0x1041);// for *very* old ACR-NEMA images + std::string StrSliceLocation = GetEntryByNumber(0x0020,0x1041);// for *very* old ACR-NEMA images if (StrSliceLocation != GDCM_UNFOUND) { if( sscanf( StrSliceLocation.c_str(), "%f", &zImPos) !=1) { dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Slice Location (0020,1041)"); @@ -430,7 +430,7 @@ float gdcmHeaderHelper::GetZOrigin() { } } dbg.Verbose(0, "gdcmHeader::GetZImagePosition: unfound Slice Location (0020,1041)"); - std::string StrLocation = GetPubEntryByNumber(0x0020,0x0050); + std::string StrLocation = GetEntryByNumber(0x0020,0x0050); if (StrLocation != GDCM_UNFOUND) { if( sscanf( StrLocation.c_str(), "%f", &zImPos) !=1) { dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Location (0020,0050)"); @@ -455,7 +455,7 @@ int gdcmHeaderHelper::GetImageNumber() { //binary conversion rules. This may be preferable to sscanf() since atoi() is a much smaller, // simpler and faster function. sscanf() can do all possible conversions whereas atoi() can //only do single decimal integer conversions. - std::string StrImNumber = GetPubEntryByNumber(0x0020,0x0013); //0020 0013 IS REL Image Number + std::string StrImNumber = GetEntryByNumber(0x0020,0x0013); //0020 0013 IS REL Image Number if (StrImNumber != GDCM_UNFOUND) { return atoi( StrImNumber.c_str() ); } @@ -468,7 +468,7 @@ int gdcmHeaderHelper::GetImageNumber() { * @return ModalityType */ ModalityType gdcmHeaderHelper::GetModality(void) { - std::string StrModality = GetPubEntryByNumber(0x0008,0x0060); //0008 0060 CS ID Modality + std::string StrModality = GetEntryByNumber(0x0008,0x0060); //0008 0060 CS ID Modality if (StrModality != GDCM_UNFOUND) { if ( StrModality.find("AU") < StrModality.length()) return AU; else if ( StrModality.find("AS") < StrModality.length()) return AS; @@ -531,7 +531,7 @@ void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) { //iop is supposed to be float[6] iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0; - std::string StrImOriPat = GetPubEntryByNumber(0x0020,0x0037); // 0020 0037 DS REL Image Orientation (Patient) + std::string StrImOriPat = GetEntryByNumber(0x0020,0x0037); // 0020 0037 DS REL Image Orientation (Patient) if (StrImOriPat != GDCM_UNFOUND) { if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) { @@ -543,7 +543,7 @@ void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) { } //For ACR-NEMA - StrImOriPat = GetPubEntryByNumber(0x0020,0x0035); //0020 0035 DS REL Image Orientation (RET) + StrImOriPat = GetEntryByNumber(0x0020,0x0035); //0020 0035 DS REL Image Orientation (RET) if (StrImOriPat != GDCM_UNFOUND) { if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) { diff --git a/src/gdcmParse.cxx b/src/gdcmParse.cxx index 7936e69a..c388cb54 100644 --- a/src/gdcmParse.cxx +++ b/src/gdcmParse.cxx @@ -51,7 +51,7 @@ bool gdcmFile::ParsePixelData(void) { } int nb; - std::string str_nb=Header->GetPubEntryByNumber(0x0028,0x0100); + std::string str_nb=Header->GetEntryByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; } else {