From ec2e18e4b67fae08879a7428560e1c021ed11d6d Mon Sep 17 00:00:00 2001 From: jpr Date: Thu, 16 Jan 2003 17:31:27 +0000 Subject: [PATCH] modif DcmWrite --- src/gdcm.h | 28 +++-- src/gdcmDict.cxx | 26 ++--- src/gdcmElValSet.cxx | 241 +++++++++++++++++++++++++++---------------- src/gdcmHeader.cxx | 6 +- 4 files changed, 183 insertions(+), 118 deletions(-) diff --git a/src/gdcm.h b/src/gdcm.h index 1b387098..c2c139c0 100644 --- a/src/gdcm.h +++ b/src/gdcm.h @@ -255,31 +255,37 @@ public: ElValue(gdcmDictEntry*); void SetDictEntry(gdcmDictEntry *NewEntry) { entry = NewEntry; }; bool IsVrUnknown(void) { return entry->IsVrUnknown(); }; - void SetImplicitVr(void) { ImplicitVr = true; }; - bool IsImplicitVr(void) { return ImplicitVr; }; + void SetImplicitVr(void) { ImplicitVr = true; }; + bool IsImplicitVr(void) { return ImplicitVr; }; - guint16 GetGroup(void) { return entry->GetGroup(); }; - guint16 GetElement(void) { return entry->GetElement(); }; - string GetKey(void) { return entry->GetKey(); }; - string GetName(void) { return entry->GetName(); }; + guint16 GetGroup(void) { return entry->GetGroup(); }; + guint16 GetElement(void) { return entry->GetElement(); }; + string GetKey(void) { return entry->GetKey(); }; + string GetName(void) { return entry->GetName(); }; - string GetVR(void) { return entry->GetVR(); }; - void SetVR(string v) { entry->SetVR(v); }; + string GetVR(void) { return entry->GetVR(); }; + void SetVR(string v) { entry->SetVR(v); }; // Question : // Un champ privé, accessible en consultation et en modif (sans restriction) // interet par rapport à un champ public ? // --> pouvoir en changer la définition sans toucher à l'API - + void SetLength(guint32 l){ LgrElem = l; }; guint32 GetLength(void) { return LgrElem; }; + + // Question : SetLength est public + // (sinon, on ne pourrait pas l'appeler dans ElValSet) + // alors que *personne* ne devrait s'en servir ! + // c'est *forcément* la lgr de la string 'value', non? void SetValue(string val){ value = val; }; string GetValue(void) { return value; }; void SetOffset(size_t of){ Offset = of; }; - size_t GetOffset(void) { return Offset; }; - + size_t GetOffset(void) { return Offset; }; + // Question : SetOffset est public ... + // Quel utilisateur serait ammené à modifier l'Offset ? }; diff --git a/src/gdcmDict.cxx b/src/gdcmDict.cxx index da9423b8..70768a0d 100644 --- a/src/gdcmDict.cxx +++ b/src/gdcmDict.cxx @@ -57,13 +57,14 @@ int gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) { // au cas ou la NewEntry serait incomplete // Question : cela peut-il se produire ? // - TagKey key; - key = NewEntry->GetKey(); - if (key =="") { - NewEntry->gdcmDictEntry::SetKey( - gdcmDictEntry::TranslateToKey(NewEntry->GetGroup(), NewEntry->GetElement()) - ); - } + // --> NON : voir constructeur + //TagKey key; + //key = NewEntry->GetKey(); + //if (key =="") { + // NewEntry->gdcmDictEntry::SetKey( + // gdcmDictEntry::TranslateToKey(NewEntry->GetGroup(), NewEntry->GetElement()) + // ); + //} entries.erase (NewEntry->gdcmDictEntry::GetKey()); entries[ NewEntry->GetKey()] = NewEntry; @@ -74,18 +75,9 @@ int gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) { int gdcmDict::AddNewEntry(gdcmDictEntry* NewEntry) { - // au cas ou la NewEntry serait incomplete - // Question : cela peut-il se produire ? - // - TagKey key; key = NewEntry->GetKey(); - if (key =="") { - NewEntry->SetKey( - gdcmDictEntry::TranslateToKey(NewEntry->GetGroup(), NewEntry->GetElement()) - ); - } - + if(entries.count(key) >= 1) { printf("gdcmDict::AddNewEntry %s deja present\n", key.c_str()); return(0); diff --git a/src/gdcmElValSet.cxx b/src/gdcmElValSet.cxx index 54200c68..39ba3c1a 100644 --- a/src/gdcmElValSet.cxx +++ b/src/gdcmElValSet.cxx @@ -21,8 +21,89 @@ void ElValSet::Print(ostream & os) { os << "[" << tag->second->GetName() << "]"; os << "[" << tag->second->GetVR() << "]" << endl; } +} + +void ElValSet::PrintByName(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; + } +} + +ElValue* ElValSet::GetElementByNumber(guint32 group, guint32 element) { + TagKey key = gdcmDictEntry::TranslateToKey(group, element); + if ( ! tagHt.count(key)) + return (ElValue*)0; + if (tagHt.count(key) > 1) + dbg.Verbose(0, "ElValSet::GetElementByNumber", + "multiple entries for this key (FIXME) !"); + return tagHt.find(key)->second; +} + +ElValue* ElValSet::GetElementByName(string TagName) { + if ( ! NameHt.count(TagName)) + return (ElValue*)0; + if (NameHt.count(TagName) > 1) + dbg.Verbose(0, "ElValSet::GetElement", + "multipe entries for this key (FIXME) !"); + return NameHt.find(TagName)->second; +} + +string ElValSet::GetElValueByNumber(guint32 group, guint32 element) { + TagKey key = gdcmDictEntry::TranslateToKey(group, element); + if ( ! tagHt.count(key)) + return "gdcm::Unfound"; + if (tagHt.count(key) > 1) + dbg.Verbose(0, "ElValSet::GetElValueByNumber", + "multiple entries for this key (FIXME) !"); + return tagHt.find(key)->second->GetValue(); +} + +string ElValSet::GetElValueByName(string TagName) { + if ( ! NameHt.count(TagName)) + return "gdcm::Unfound"; + if (NameHt.count(TagName) > 1) + dbg.Verbose(0, "ElValSet::GetElValue", + "multipe entries for this key (FIXME) !"); + return NameHt.find(TagName)->second->GetValue(); +} + +int ElValSet::SetElValueByNumber(string content, guint32 group, guint32 element) { + TagKey key = gdcmDictEntry::TranslateToKey(group, element); + if ( ! tagHt.count(key)) + return 0; + if (tagHt.count(key) > 1) { + dbg.Verbose(0, "ElValSet::SetElValueByNumber", + "multiple entries for this key (FIXME) !"); + return (0); + } + tagHt[key]->SetValue(content); + // Question : m à j LgrElem ? + tagHt[key]->SetLength(strlen(content.c_str())); + // Ou trouver les fonctions d'une classe donnée? + // lgr d'une string, p.ex + return(1); +} + + +int ElValSet::SetElValueByName(string content, string TagName) { + if ( ! NameHt.count(TagName)) + return 0; + if (NameHt.count(TagName) > 1) { + dbg.Verbose(0, "ElValSet::SetElValue", + "multipe entries for this key (FIXME) !"); + return 0; + } + NameHt.find(TagName)->second->SetValue(content); + NameHt.find(TagName)->second->SetLength(strlen(content.c_str())); + return(1); } - + + int ElValSet::Write(FILE * _fp) { @@ -30,31 +111,91 @@ int ElValSet::Write(FILE * _fp) { guint16 gr, el; guint32 lgr; - const char * val; string vr; guint32 val_int32; guint16 val_int16; void *ptr; + string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; + +/* // Utilisées pour le calcul Group Length + int deja = 0; + guint32 lgrCalcGroupe; + ElValue * elemZ, *elemZPrec; + guint16 grCourant = 0; - // A FAIRE : - // parcourir la table pour recalculer la longueur des 'elements 0x0000' +*/ + + // Question : + // Comment pourrait-on tester si on est TRueDicom ou non , + // (FileType est un champ de gdcmHeader ...) + // + + // 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 // // cf : code IdDcmWriteFile - -/* + +/* + // Pas le temps de finir + // voir libido/src/dcmwrite.c + // + // mais avant ... voir si le 'group length', lorsqu'il est present + // sert encore a qq chose + // patcher une image DICOM, mettre une lgr erronnée + // et voir si e-film la reconnait ... + + for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); ++tag){ - / ... - + elemZ = tag->second; + + if ( (elemZ->GetGroup() != grCourant) && + (elemZ->GetGroup() != 0xfffe) ) { // On arrive sur un nv Groupe + + if(elemZ->GetNum != 0x0000) { // pas d'element 'Lgr groupe' + // On le crée + gdcmDictEntry * tagZ = IsInDicts(tag->second->GetGroup(), 0); + elemZ = new (ElValue(tagZ)); // on le cree + elemZ.SetLength(4); + Add(elemZ); // On l'accroche à sa place + } + + if (deja) { + + // A FINIR + } + deja = 1; + elemZPrec = elemZ; + grCourant = elemZ->GetGroup(); + lgrCalcGroupe = 12; //2 + 2 + 4 + 4; // lgr (Gr + Num + LgrElem + LgrGroupe) + + } else { // On n'EST PAS sur un nv Groupe + + lgrCalcGroupe += 2 + 2; // lgr (Gr + Num ) + + if (IsVrUnknowkn()) { + + // A FINIR + + } + + // A FINIR } + */ - // resteront à tester les echecs en écriture + + // Si on fait de l'implicit VR littele Endian + // (pour moins se fairche sur processeur INTEL) + // penser a forcer le SYNTAX TRANSFERT UID + + SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010); + + // restent à tester les echecs en écriture (apres chaque fwrite) for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); @@ -75,8 +216,8 @@ int ElValSet::Write(FILE * _fp) { fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp); //VR - // voir pb lgr + VR - // On fait de l'implicit VR (penser a forcer le SYNTAX TRANSFERT UID) + + // si on n'est pas en IMPLICIT VR voir pb (lgr + VR) fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp); //lgr @@ -101,81 +242,3 @@ int ElValSet::Write(FILE * _fp) { return(1); } - - - -void ElValSet::PrintByName(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; - } -} - -ElValue* ElValSet::GetElementByNumber(guint32 group, guint32 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHt.count(key)) - return (ElValue*)0; - if (tagHt.count(key) > 1) - dbg.Verbose(0, "ElValSet::GetElementByNumber", - "multiple entries for this key (FIXME) !"); - return tagHt.find(key)->second; -} - -ElValue* ElValSet::GetElementByName(string TagName) { - if ( ! NameHt.count(TagName)) - return (ElValue*)0; - if (NameHt.count(TagName) > 1) - dbg.Verbose(0, "ElValSet::GetElement", - "multipe entries for this key (FIXME) !"); - return NameHt.find(TagName)->second; -} - -string ElValSet::GetElValueByNumber(guint32 group, guint32 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHt.count(key)) - return "gdcm::Unfound"; - if (tagHt.count(key) > 1) - dbg.Verbose(0, "ElValSet::GetElValueByNumber", - "multiple entries for this key (FIXME) !"); - return tagHt.find(key)->second->GetValue(); -} - -int ElValSet::SetElValueByNumber(string content, guint32 group, guint32 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); - if ( ! tagHt.count(key)) - return 0; - if (tagHt.count(key) > 1) { - dbg.Verbose(0, "ElValSet::SetElValueByNumber", - "multiple entries for this key (FIXME) !"); - return (0); - } - - tagHt[key]->SetValue(content); - return(1); -} - -string ElValSet::GetElValueByName(string TagName) { - if ( ! NameHt.count(TagName)) - return "gdcm::Unfound"; - if (NameHt.count(TagName) > 1) - dbg.Verbose(0, "ElValSet::GetElValue", - "multipe entries for this key (FIXME) !"); - return NameHt.find(TagName)->second->GetValue(); -} - -int ElValSet::SetElValueByName(string content, string TagName) { - if ( ! NameHt.count(TagName)) - return 0; - if (NameHt.count(TagName) > 1) { - dbg.Verbose(0, "ElValSet::SetElValue", - "multipe entries for this key (FIXME) !"); - return 0; - } - NameHt.find(TagName)->second->SetValue(content); -} - - diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 361aedd8..6eeebe41 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -124,7 +124,7 @@ void gdcmHeader::CheckSwap() net2host = false; // The easiest case is the one of a DICOM header, since it possesses a - // file preamble where it suffice to look for the sting "DICM". + // file preamble where it suffice to look for the string "DICM". lgrLue = fread(deb, 1, HEADER_LENGTH_TO_READ, fp); entCur = deb + 128; @@ -500,6 +500,8 @@ bool gdcmHeader::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) { // // --> probablement TOUS les supprimer (Eric dixit) // + + void gdcmHeader::FixFoundLength(ElValue * ElVal, guint32 FoundLength) { // Heuristic: a final fix. if ( FoundLength == 0xffffffff) @@ -730,6 +732,8 @@ void gdcmHeader::LoadElementValue(ElValue * ElVal) { // each element of the group shall be loaded individualy. if( elem == 0 ) //SkipLoad = true; // modif sauvage JPR + // On charge la longueur du groupe + // quand l'element 0x0000 est présent ! if ( SkipLoad ) { // FIXME the following skip is not necessary -- 2.48.1