From: jpr Date: Tue, 8 Apr 2003 17:10:58 +0000 (+0000) Subject: fonction UpdateGroupLengthNew (utilisant une HTable) X-Git-Tag: Version0.3~65 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=4ea2f357cc50dd9238c6bdf4f29c275aab1aa1a9;p=gdcm.git fonction UpdateGroupLengthNew (utilisant une HTable) qui remplacera UpdateGroupLength, commitee par precaution. --- diff --git a/ChangeLog b/ChangeLog index 343253fc..3690e73e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,14 @@ +2003-04-7 JPR + * UpdateGroupLength re-written using H-Table + (named UpdateGroupLengthNew untill checks are over) + 2003-04-7 Eric Boix with JPR * Data/im_00001 renamed to gdcm-MR-PHILIPS-16-Multi-Seq.dcm * src: - gdcmHeader::GetPubElValSet removed. - gdcmElValSet::WriteDcm, WriteAcr, WriteExplVR, revamped to UpdateGroupLength, WriteElements, Write. + - enum FileType moved to gdcmCommon.h * Test/*.cxx changed to agree with above changes 2003-03-31 Eric Boix diff --git a/src/gdcmCommon.h b/src/gdcmCommon.h index f243d842..5c2b3805 100644 --- a/src/gdcmCommon.h +++ b/src/gdcmCommon.h @@ -39,7 +39,7 @@ enum FileType { ImplicitVR, ACR, ACR_LIBIDO -}; // CLEANME +}; #endif diff --git a/src/gdcmElValSet.cxx b/src/gdcmElValSet.cxx index 9b001c5d..fe5df937 100644 --- a/src/gdcmElValSet.cxx +++ b/src/gdcmElValSet.cxx @@ -119,6 +119,10 @@ int gdcmElValSet::SetElValueLengthByName(guint32 length, string TagName) { } void gdcmElValSet::UpdateGroupLength(bool SkipSequence) { + + // TODO : reecrire entierement : une HTable dans la quelle on stocke les groupes, puis leur lgr + // Voir juste apres + // On parcourt la table pour recalculer la longueur des 'elements 0x0000' // au cas ou un tag ai été ajouté par rapport à ce qui a été lu // dans l'image native @@ -163,15 +167,13 @@ void gdcmElValSet::UpdateGroupLength(bool SkipSequence) { el = elem->GetElement(); vr = elem->GetVR(); - if (SkipSequence && vr == "SQ") + if (SkipSequence && vr == "SQ") continue; // pas SEQUENCE en ACR-NEMA - // WARNING : risque de pb + // WARNING : pb CERTAIN // si on est descendu 'a l'interieur' des SQ - continue; - // - // - if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe - (el != 0xfffe) */ ) { + + if ( (gr != grCourant) /*&& // On arrive sur un nv Groupe + (el != 0xfffe) */ ) { if (el != 0x0000) { gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL"); @@ -194,7 +196,10 @@ void gdcmElValSet::UpdateGroupLength(bool SkipSequence) { if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl; elemZPrec=elemZ; lgrCalcGroupe = 0; - grCourant = gr; + grCourant = gr; + // BUG : + // calcule lgr erronnée si ExplicitVR et VR =OB, SQ, etc + // if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr); } else { // On n'EST PAS sur un nv Groupe lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength(); // Gr + Num + Lgr + LgrElem @@ -202,8 +207,65 @@ void gdcmElValSet::UpdateGroupLength(bool SkipSequence) { elem->GetLength(), el, lgrCalcGroupe, gr); } } + + // BUG : + // Ecriture incorrecte si (7FE0 0000) absent et aucun element apres groupe 7FE0 :-( + // A JETTER ! + // +} + +// +// Remplacera UpdateGroupLength +// Commite par precaution. +// Ne pas utiliser +// + +void gdcmElValSet::UpdateGroupLengthNew(bool SkipSequence, FileType type) { + guint16 gr, el; + string vr; + + gdcmElValue *elem; + char trash[10]; + GroupKey key; + GroupHT groupHt; + + for (TagElValueHT::iterator tag2 = tagHt.begin(); + tag2 != tagHt.end(); + ++tag2){ + + elem = tag2->second; + gr = elem->GetGroup(); + el = elem->GetElement(); + vr = elem->GetVR(); + + sprintf(trash, "%04x", gr); + key = trash; + + if (SkipSequence && vr == "SQ") continue; + // pas SEQUENCE en ACR-NEMA + // WARNING : pb CERTAIN + // si on est descendu 'a l'interieur' des SQ + // + // --> la descente a l'interieur' des SQ + // devra etre faite avec une liste chainee, pas avec une HTable... + + if ( groupHt.count(key) == 0) { + groupHt[key] = 2 + 2 + 4 + 4; // creation automatique, par affectation ??? + } else { + if (type = ExplicitVR) { + if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) { + groupHt[key] += 4; + } + } + groupHt[key] += 2 + 2 + 4 + elem->GetLength(); + } + } + + // Liberer groupHt ! } + + void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { guint16 gr, el; guint32 lgr; @@ -211,13 +273,15 @@ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { string vr; guint32 val_uint32; guint16 val_uint16; - + vector tokens; void *ptr; - // restent à tester les echecs en écriture (apres chaque fwrite) - for (TagElValueHT::iterator tag2 = tagHt.begin(); + // Tout ceci ne marche QUE parce qu'on est sur un proc Little Endian + // restent à tester les echecs en écriture (apres chaque fwrite) + + for (TagElValueHT::iterator tag2=tagHt.begin(); tag2 != tagHt.end(); ++tag2){ @@ -234,7 +298,6 @@ void gdcmElValSet::WriteElements(FileType type, FILE * _fp) { if (vr == "SQ" ) continue; } - fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element @@ -287,11 +350,20 @@ 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 si le DcmHeader vient d'un fichoer 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); diff --git a/src/gdcmElValSet.h b/src/gdcmElValSet.h index a8c4cdf5..7fc07ce3 100644 --- a/src/gdcmElValSet.h +++ b/src/gdcmElValSet.h @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.8 2003/04/08 15:03:35 frog Exp $ +// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.9 2003/04/08 17:10:58 jpr Exp $ #ifndef GDCMELVALSET_H #define GDCMELVALSET_H @@ -14,35 +14,39 @@ typedef map TagElValueHT; typedef map TagElValueNameHT; class GDCM_EXPORT gdcmElValSet { - TagElValueHT tagHt; // Both accesses with a TagKey or with a - TagElValueNameHT NameHt; // the DictEntry.Name are required. -//FIXME This is redundant with gdcmHeader::FileType enum. That sux ! + TagElValueHT tagHt; // Both accesses with a TagKey or with a + TagElValueNameHT NameHt; // the DictEntry.Name are required. + + typedef string GroupKey; + typedef map GroupHT; + public: - void Add(gdcmElValue*); - // TODO - //void ReplaceOrCreate(gdcmElValue*); - void Print(ostream &); - void PrintByName(ostream &); - int Write(FILE *fp, FileType type); - - gdcmElValue* GetElementByNumber(guint16 group, guint16 element); - gdcmElValue* GetElementByName (string); - string GetElValueByNumber(guint16 group, guint16 element); - string GetElValueByName (string); + void Add(gdcmElValue*); + + void Print(ostream &); + void PrintByName(ostream &); + int Write(FILE *fp, FileType type); + + gdcmElValue* GetElementByNumber(guint16 group, guint16 element); + gdcmElValue* GetElementByName (string); + string GetElValueByNumber(guint16 group, guint16 element); + string GetElValueByName (string); - TagElValueHT & GetTagHt(void); + TagElValueHT & GetTagHt(void); - int SetElValueByNumber(string content, guint16 group, guint16 element); - int SetElValueByName (string content, string TagName); + int SetElValueByNumber(string content, guint16 group, guint16 element); + int SetElValueByName (string content, string TagName); - int SetElValueLengthByNumber(guint32 l, guint16 group, guint16 element); - int SetElValueLengthByName (guint32 l, string TagName); + int SetElValueLengthByNumber(guint32 l, guint16 group, guint16 element); + int SetElValueLengthByName (guint32 l, string TagName); guint32 GenerateFreeTagKeyInGroup(guint16 group); private: void UpdateGroupLength(bool SkipSequence = false); void WriteElements(FileType type, FILE *); + + void UpdateGroupLengthNew(bool SkipSequence = false, FileType type = ImplicitVR); };