X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmElValSet.cxx;h=7678bddb876a46615fd30a7ae0de1cbc6f61f074;hb=8fb1011e6fca9654c69d4921642f18146c66ca7f;hp=ae4de17bdd77c3238763a34a66863ae569a6f50c;hpb=d44cb38c3275dc302d9b523c17d346810f0e6644;p=gdcm.git diff --git a/src/gdcmElValSet.cxx b/src/gdcmElValSet.cxx index ae4de17b..7678bddb 100644 --- a/src/gdcmElValSet.cxx +++ b/src/gdcmElValSet.cxx @@ -1,19 +1,9 @@ // gdcmElValSet.cxx -#ifdef _MSC_VER -// 'identifier' : class 'type' needs to have dll-interface to be used by -// clients of class 'type2' -#pragma warning ( disable : 4251 ) -// 'identifier' : identifier was truncated to 'number' characters in the -// debug information -#pragma warning ( disable : 4786 ) -#endif //_MSC_VER - -#include #include "gdcmUtil.h" #include "gdcmElValSet.h" #include "gdcmTS.h" -using namespace std; +#include gdcmElValSet::~gdcmElValSet() { for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); ++tag) { @@ -32,6 +22,11 @@ TagElValueHT & gdcmElValSet::GetTagHt(void) { return tagHt; } + +ListTag & gdcmElValSet::GetListElem(void) { + return listElem; +} + /** * \ingroup gdcmElValSet * \brief @@ -41,6 +36,11 @@ TagElValueHT & gdcmElValSet::GetTagHt(void) { void gdcmElValSet::Add(gdcmElValue * newElValue) { tagHt [newElValue->GetKey()] = newElValue; NameHt[newElValue->GetName()] = newElValue; + +// WARNING : push_bash in listElem ONLY during ParseHeader +// TODO : something to allow further Elements addition +// position to be taken care of ! + listElem.push_back(newElValue); } /** @@ -52,7 +52,7 @@ void gdcmElValSet::Add(gdcmElValue * newElValue) { * @return */ int gdcmElValSet::CheckIfExistByNumber(guint16 Group, guint16 Elem ) { - string key = TranslateToKey(Group, Elem ); + std::string key = TranslateToKey(Group, Elem ); return (tagHt.count(key)); } @@ -60,15 +60,16 @@ int gdcmElValSet::CheckIfExistByNumber(guint16 Group, guint16 Elem ) { * \ingroup gdcmElValSet * \brief */ -void gdcmElValSet::Print(ostream & os) { +void gdcmElValSet::Print(std::ostream & os) { size_t o; short int g, e; TSKey v; - char * d; - string d2; + std::string d2; gdcmTS * ts = gdcmGlobal::GetTS(); + std::cout << "------------- using tagHt ----------------------------" << std::endl; + for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); ++tag){ @@ -76,13 +77,12 @@ void gdcmElValSet::Print(ostream & os) { e = tag->second->GetElement(); v = tag->second->GetValue(); o = tag->second->GetOffset(); - d = _CreateCleanString(v); // replace non printable characters by '.' - d2=d; + d2 = _CreateCleanString(v); // replace non printable characters by '.' os << tag->first << ": "; os << " lgr : " << tag->second->GetLength(); os << ", Offset : " << o; - os << " x(" << hex << o << dec << ") "; + os << " x(" << std::hex << o << std::dec << ") "; os << "\t[" << tag->second->GetVR() << "]"; os << "\t[" << tag->second->GetName() << "]"; os << "\t[" << d2 << "]"; @@ -97,23 +97,59 @@ void gdcmElValSet::Print(ostream & os) { os << " ==>\t[" << ts->GetValue(v) << "]"; } } - free(d); - os << endl; + os << std::endl; } + + std::cout << "------------ using listElem -----------------" << std::endl; + + //for (ListTag::iterator i = listElem.begin(); + + char tag[9]; + + for (std::list::iterator i = listElem.begin(); + i != listElem.end(); + ++i){ + sprintf(tag,"%04x|%04x",(*i)->GetGroup(),(*i)->GetElement()); + g = (*i)->GetGroup(); + e = (*i)->GetElement(); + v = (*i)->GetValue(); + o = (*i)->GetOffset(); + d2 = _CreateCleanString(v); // replace non printable characters by '.' + //os << std::hex <GetReadLength(); + os << ", Offset : " << o; + os << " x(" << std::hex << o << std::dec << ") "; + os << "\t[" << (*i)->GetVR() << "]"; + os << "\t[" << (*i)->GetName() << "]"; + os << "\t[" << d2 << "]"; + + // Display the UID value (instead of displaying the rough code) + if (g == 0x0002) { // Any more to be displayed ? + if ( (e == 0x0010) || (e == 0x0002) ) + os << " ==>\t[" << ts->GetValue(v) << "]"; + } else { + if (g == 0x0008) { + if ( (e == 0x0016) || (e == 0x1150) ) + os << " ==>\t[" << ts->GetValue(v) << "]"; + } + } + os << std::endl; + } } /** * \ingroup gdcmElValSet * \brief */ -void gdcmElValSet::PrintByName(ostream & os) { +void gdcmElValSet::PrintByName(std::ostream & os) { for (TagElValueNameHT::iterator tag = NameHt.begin(); tag != NameHt.end(); ++tag){ os << tag->first << ": "; os << "[" << tag->second->GetValue() << "]"; os << "[" << tag->second->GetKey() << "]"; - os << "[" << tag->second->GetVR() << "]" << endl; + os << "[" << tag->second->GetVR() << "]" << std::endl; } } @@ -136,7 +172,7 @@ gdcmElValue* gdcmElValSet::GetElementByNumber(guint16 group, guint16 element) { * \brief * @return */ -gdcmElValue* gdcmElValSet::GetElementByName(string TagName) { +gdcmElValue* gdcmElValSet::GetElementByName(std::string TagName) { if ( ! NameHt.count(TagName)) return (gdcmElValue*)0; return NameHt.find(TagName)->second; @@ -149,7 +185,7 @@ gdcmElValue* gdcmElValSet::GetElementByName(string TagName) { * @param element * @return */ -string gdcmElValSet::GetElValueByNumber(guint16 group, guint16 element) { +std::string gdcmElValSet::GetElValueByNumber(guint16 group, guint16 element) { TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHt.count(key)) return GDCM_UNFOUND; @@ -161,7 +197,7 @@ string gdcmElValSet::GetElValueByNumber(guint16 group, guint16 element) { * \brief * @return */ -string gdcmElValSet::GetElValueByName(string TagName) { +std::string gdcmElValSet::GetElValueByName(std::string TagName) { if ( ! NameHt.count(TagName)) return GDCM_UNFOUND; return NameHt.find(TagName)->second->GetValue(); @@ -175,13 +211,19 @@ string gdcmElValSet::GetElValueByName(string TagName) { * @param element * @return */ -int gdcmElValSet::SetElValueByNumber(string content, +int gdcmElValSet::SetElValueByNumber(std::string content, guint16 group, guint16 element) { TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHt.count(key)) return 0; - tagHt[key]->SetValue(content); - string vr = tagHt[key]->GetVR(); + int l = content.length(); + if(l%2) { // Odd length are padded with a space (020H). + l++; + content = content + '\0'; + } + tagHt[key]->SetValue(content); + + std::string vr = tagHt[key]->GetVR(); guint32 lgr; if( (vr == "US") || (vr == "SS") ) @@ -189,7 +231,7 @@ int gdcmElValSet::SetElValueByNumber(string content, else if( (vr == "UL") || (vr == "SL") ) lgr = 4; else - lgr = content.length(); + lgr = l; tagHt[key]->SetLength(lgr); return 1; } @@ -201,11 +243,20 @@ int gdcmElValSet::SetElValueByNumber(string content, * @param TagName * @return */ -int gdcmElValSet::SetElValueByName(string content, string TagName) { +int gdcmElValSet::SetElValueByName(std::string content, std::string TagName) { if ( ! NameHt.count(TagName)) return 0; + int l = content.length(); + if(l%2) { // Odd length are padded with a space (020H). + l++; + // Well. I know that '/0' is NOT a space + // but it doesn't work with a space. + // Use hexedit and see 0002|0010 value (Transfer Syntax UID) + content = content + '\0'; + } NameHt[TagName]->SetValue(content); - string vr = NameHt[TagName]->GetVR(); + + std::string vr = NameHt[TagName]->GetVR(); guint32 lgr; if( (vr == "US") || (vr == "SS") ) @@ -269,6 +320,7 @@ int gdcmElValSet::SetElValueLengthByNumber(guint32 length, TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHt.count(key)) return 0; + if (length%2) length++; // length must be even tagHt[key]->SetLength(length); return 1 ; } @@ -279,9 +331,10 @@ int gdcmElValSet::SetElValueLengthByNumber(guint32 length, * @param TagName * @return */ -int gdcmElValSet::SetElValueLengthByName(guint32 length, string TagName) { +int gdcmElValSet::SetElValueLengthByName(guint32 length, std::string TagName) { if ( ! NameHt.count(TagName)) return 0; + if (length%2) length++; // length must be even NameHt.find(TagName)->second->SetLength(length); return 1 ; } @@ -294,11 +347,11 @@ int gdcmElValSet::SetElValueLengthByName(guint32 length, string TagName) { */ void gdcmElValSet::UpdateGroupLength(bool SkipSequence, FileType type) { guint16 gr, el; - string vr; + std::string vr; gdcmElValue *elem; char trash[10]; - string str_trash; + std::string str_trash; GroupKey key; GroupHT groupHt; // to hold the length of each group @@ -379,25 +432,34 @@ void gdcmElValSet::UpdateGroupLength(bool SkipSequence, FileType type) { /** * \ingroup gdcmElValSet - * \brief - * @param type - * @param _fp + * \brief writes on disc according to the requested format + * \ (ACR-NEMA, DICOM, RAW) the image + * \ warning does NOT add the missing elements in the header : + * \ it's up to the user doing it ! + * \ (function CheckHeaderCoherence to be written) + * @param type type of the File to be written + * (ACR-NEMA, DICOM, RAW) + * @param _fp already open file pointer * @return */ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { guint16 gr, el; guint32 lgr; const char * val; - string vr; + std::string vr; guint32 val_uint32; guint16 val_uint16; - vector tokens; + std::vector tokens; + + // TODO : use listElem to iterate, not TagHt! + // pb : gdcmElValSet.Add does NOT update listElem + // find a trick in STL to do it, at low cost ! void *ptr; // Tout ceci ne marche QUE parce qu'on est sur un proc Little Endian - // restent à tester les echecs en écriture (apres chaque fwrite) + // restent a tester les echecs en ecriture (apres chaque fwrite) for (TagElValueHT::iterator tag2=tagHt.begin(); tag2 != tagHt.end(); @@ -409,7 +471,7 @@ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { val = tag2->second->GetValue().c_str(); vr = tag2->second->GetVR(); - // cout << "Tag "<< hex << gr << " " << el << "\n"; + // std::cout << "Tag "<< std::hex << gr << " " << el << std::endl; if ( type == ACR ) { if (gr < 0x0008) continue; // ignore pure DICOM V3 groups @@ -476,28 +538,13 @@ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { */ int gdcmElValSet::Write(FILE * _fp, FileType type) { - if (type == ImplicitVR) { - string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; - SetElValueByNumber(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 - - SetElValueLengthByNumber(18, 0x0002, 0x0010); - } // Question : - // Comment pourrait-on savoir si le DcmHeader vient d'un fichier DicomV3 ou non , + // 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 - - if (type == ExplicitVR) { - string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1"; - SetElValueByNumber(explicitVRTransfertSyntax, 0x0002, 0x0010); - // See above comment - SetElValueLengthByNumber(20, 0x0002, 0x0010); - } + // no way + // a moins de se livrer a un tres complique ajout des champs manquants. + // faire un CheckAndCorrectHeader (?) if ( (type == ImplicitVR) || (type == ExplicitVR) ) UpdateGroupLength(false,type);