From 75262e67ec39ad2f359c1efbf9ee805819a8e58a Mon Sep 17 00:00:00 2001 From: jpr Date: Tue, 15 Jun 2004 08:41:09 +0000 Subject: [PATCH] Jean-Pierre Roux gdcmBinEntry.cxx - adding a constructor taking a gdcmDocEntry as an input param - ReplaceOrCreateByNumber now returns : a gdcmBinEntry * if a Binary (void *) value is passed as a param a gdcmValEntry * if a string value is passed as a param gdcmDocument.cxx - SetEntryByNumber now allows setting gdcmValEntry or gdcmBinEntry, according to the param type (no longer sets a gdcmDocEntry) - GetValEntryByNumber, GetBinEntryByNumber added - NewValEntryByNumber and NewBinEntryByNumber added gdcmFile.cxx - Pixel Data are now linked to the (7fe0,0010) elements, after reading gdcmSQItem.h - GetSQItemNumber and SetSQItemNumber added, to provide a (relative) Item identier inside a given Sequence \warning : some pb remaining around this number will be solved asap - AddEntry now takes the Item Number as a param gdcmValEntry.cxx - adding a constructor taking a gdcmDocEntry as an input param --- src/gdcmBinEntry.cxx | 15 ++++ src/gdcmBinEntry.h | 3 +- src/gdcmDocument.cxx | 158 ++++++++++++++++++++++++++++++++++++------- src/gdcmDocument.h | 20 +++++- src/gdcmFile.cxx | 2 +- src/gdcmSQItem.cxx | 1 + src/gdcmSQItem.h | 7 +- src/gdcmSeqEntry.cxx | 13 ++-- src/gdcmSeqEntry.h | 2 +- src/gdcmValEntry.cxx | 17 +++++ src/gdcmValEntry.h | 3 +- 11 files changed, 204 insertions(+), 37 deletions(-) diff --git a/src/gdcmBinEntry.cxx b/src/gdcmBinEntry.cxx index 376e86f9..4498e27f 100644 --- a/src/gdcmBinEntry.cxx +++ b/src/gdcmBinEntry.cxx @@ -14,6 +14,21 @@ gdcmBinEntry::gdcmBinEntry(gdcmDictEntry* e) : gdcmValEntry(e) { } +/** + * \brief Constructor from a given gdcmBinEntry + * @param e Pointer to existing Doc entry + */ +gdcmBinEntry::gdcmBinEntry(gdcmDocEntry* e) : gdcmValEntry(e->GetDictEntry()){ + this->UsableLength = e->GetLength(); + this->ReadLength = e->GetReadLength(); + this->ImplicitVR = e->IsImplicitVR(); + this->Offset = e->GetOffset(); + this->printLevel = e->GetPrintLevel(); + this->SQDepthLevel = e->GetDepthLevel(); + + this->voidArea = NULL; // let's be carefull ! +} + /** * \brief Canonical destructor. */ diff --git a/src/gdcmBinEntry.h b/src/gdcmBinEntry.h index c93f24ef..5144e03f 100644 --- a/src/gdcmBinEntry.h +++ b/src/gdcmBinEntry.h @@ -19,7 +19,8 @@ class GDCM_EXPORT gdcmBinEntry : public gdcmValEntry { public: - gdcmBinEntry(gdcmDictEntry* e); + gdcmBinEntry(gdcmDictEntry* e); + gdcmBinEntry(gdcmDocEntry* d); ~gdcmBinEntry(void); void Print(std::ostream &os = std::cout); diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 57596e4a..7476b4b0 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -564,31 +564,66 @@ bool gdcmDocument::Write(FILE *fp, FileType type) { /** * \brief Modifies the value of a given Header Entry (Dicom Element) * when it exists. Create it with the given value when unexistant. - * @param Value Value to be set + * @param Value (string) Value to be set * @param Group Group number of the Entry * @param Elem Element number of the Entry * \return pointer to the modified/created Header Entry (NULL when creation * failed). */ - - -gdcmDocEntry * gdcmDocument::ReplaceOrCreateByNumber( + +gdcmValEntry * gdcmDocument::ReplaceOrCreateByNumber( std::string Value, guint16 Group, guint16 Elem ){ gdcmDocEntry* a; + gdcmValEntry* b; a = GetDocEntryByNumber( Group, Elem); if (a == NULL) { a =NewDocEntryByNumber(Group, Elem); if (a == NULL) return NULL; - AddEntry(a); + b = new gdcmValEntry(a); + AddEntry(b); } SetEntryByNumber(Value, Group, Elem); - //a->SetValue(Value); - return(a); + b->SetValue(Value); + return (gdcmValEntry*)b; } + +/* + * \brief Modifies the value of a given Header Entry (Dicom Element) + * when it exists. Create it with the given value when unexistant. + * @param voidArea (binary) value to be set + * @param Group Group number of the Entry + * @param Elem Element number of the Entry + * \return pointer to the modified/created Header Entry (NULL when creation + * failed). + */ + + +gdcmBinEntry * gdcmDocument::ReplaceOrCreateByNumber( + void *voidArea, + int lgth, + guint16 Group, + guint16 Elem ){ + gdcmDocEntry* a; + gdcmBinEntry* b; + a = GetDocEntryByNumber( Group, Elem); + if (a == NULL) { + a =NewBinEntryByNumber(Group, Elem); + if (a == NULL) + return NULL; + b = new gdcmBinEntry(a); + AddEntry(b); + } + SetEntryByNumber(voidArea, lgth, Group, Elem); + b->SetVoidArea(voidArea); + return (gdcmBinEntry*)b; +} + + + /** * \brief Set a new value if the invoked element exists * Seems to be useless !!! @@ -729,7 +764,7 @@ bool gdcmDocument::SetEntryByName(std::string content,std::string tagName) { * \brief Accesses an existing gdcmDocEntry (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 content new value (string) to substitute with * @param group group number of the Dicom Element to modify * @param element element number of the Dicom Element to modify */ @@ -747,10 +782,10 @@ bool gdcmDocument::SetEntryByNumber(std::string content, content = content + '\0'; } - gdcmDocEntry * a; - a = tagHT[key]; + gdcmValEntry * a; + a = (gdcmValEntry *)tagHT[key]; - ((gdcmValEntry*)a)->SetValue(content); + a->SetValue(content); VRKey vr = a->GetVR(); @@ -764,7 +799,38 @@ bool gdcmDocument::SetEntryByNumber(std::string content, a->SetLength(lgr); return true; -} +} + +/** + * \brief Accesses an existing gdcmDocEntry (i.e. a Dicom Element) + * through it's (group, element) and modifies it's content with + * the given value. + * @param content new value (void *) to substitute with + * @param group group number of the Dicom Element to modify + * @param element element number of the Dicom Element to modify + */ +bool gdcmDocument::SetEntryByNumber(void *content, + int lgth, + guint16 group, + guint16 element) +{ + TagKey key = gdcmDictEntry::TranslateToKey(group, element); + if ( ! tagHT.count(key)) + return false; + +/* Hope Binray field length is never wrong + if(lgth%2) // Non even length are padded with a space (020H). + { + lgth++; + //content = content + '\0'; // fing a trick to enlarge a binary field? + } +*/ + gdcmBinEntry * a; + a = (gdcmBinEntry *)tagHT[key]; + a->SetVoidArea(content); + //a->SetLength(lgth); // ??? + return true; +} /** * \brief Accesses an existing gdcmDocEntry (i.e. a Dicom Element) @@ -1132,11 +1198,8 @@ bool gdcmDocument::WriteEntry(gdcmDocEntry *tag, FILE *_fp,FileType type) ValEntry->SetValue(ValEntry->GetValue()+"\0"); ValEntry->SetLength(ValEntry->GetReadLength()+1); } - WriteEntryTagVRLength(ValEntry, _fp, type); - std::cout << "after WriteEntryTagVRLength " << std::endl; WriteEntryValue(ValEntry, _fp, type); - std::cout << "after WriteEntryValue " << std::endl; return true; } @@ -1148,15 +1211,12 @@ bool gdcmDocument::WriteEntry(gdcmDocEntry *tag, FILE *_fp,FileType type) // bytes. When this is not the case, pad with an additional byte: /* if(length%2==1) { - Vtag->SetValue(Vtag->GetValue()+"\0"); - Vtag->SetLength(Vtag->GetReadLength()+1); + tag->SetValue(tag->GetValue()+"\0"); + tag->SetLength(tag->GetReadLength()+1); } */ - WriteEntryTagVRLength(tag, _fp, type); - std::cout << "after WriteEntryTagVRLength " << std::endl; WriteEntryValue(tag, _fp, type); - std::cout << "after WriteEntryValue " << std::endl; return true; } } @@ -1411,8 +1471,8 @@ long gdcmDocument::ParseSQ(gdcmSeqEntry *set, long offset, long l_max, bool deli lgr=ParseDES(itemSQ, NewDocEntry->GetOffset(), l, dlm_mod); - set->AddEntry(itemSQ); - SQItemNumber ++; // a voir + set->AddEntry(itemSQ,SQItemNumber); + SQItemNumber ++; if (!delim_mode && (ftell(fp)-offset) >= l_max) { break; } @@ -2470,6 +2530,56 @@ gdcmDocEntry *gdcmDocument::NewDocEntryByNumber(guint16 Group, guint16 Elem) return NewEntry; } + +/** + * \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 number of the underlying DictEntry + * @param Elem element number of the underlying DictEntry + */ +gdcmValEntry *gdcmDocument::NewValEntryByNumber(guint16 Group, guint16 Elem) +{ + // Find out if the tag we encountered is in the dictionaries: + gdcmDictEntry *DictEntry = GetDictEntryByNumber(Group, Elem); + if (!DictEntry) + DictEntry = NewVirtualDictEntry(Group, Elem); + + gdcmValEntry *NewEntry = new gdcmValEntry(DictEntry); + if (!NewEntry) + { + dbg.Verbose(1, "gdcmDocument::NewValEntryByNumber", + "failed to allocate gdcmValEntry"); + return NULL; + } + return NewEntry; +} + + +/** + * \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 number of the underlying DictEntry + * @param Elem element number of the underlying DictEntry + */ +gdcmBinEntry *gdcmDocument::NewBinEntryByNumber(guint16 Group, guint16 Elem) +{ + // Find out if the tag we encountered is in the dictionaries: + gdcmDictEntry *DictEntry = GetDictEntryByNumber(Group, Elem); + if (!DictEntry) + DictEntry = NewVirtualDictEntry(Group, Elem); + + gdcmBinEntry *NewEntry = new gdcmBinEntry(DictEntry); + if (!NewEntry) + { + dbg.Verbose(1, "gdcmDocument::NewBinEntryByNumber", + "failed to allocate gdcmBinEntry"); + return NULL; + } + return NewEntry; +} + /** * \brief Generate a free TagKey i.e. a TagKey that is not present * in the TagHt dictionary. @@ -2523,8 +2633,8 @@ gdcmDictEntry *gdcmDocument::GetDictEntryByName(std::string Name) * 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 + * @param group group number of the searched DictEntry + * @param element element number of the searched DictEntry * @return Corresponding DictEntry when it exists, NULL otherwise. */ gdcmDictEntry *gdcmDocument::GetDictEntryByNumber(guint16 group,guint16 element) diff --git a/src/gdcmDocument.h b/src/gdcmDocument.h index 96a9aea3..eb0452dd 100644 --- a/src/gdcmDocument.h +++ b/src/gdcmDocument.h @@ -10,6 +10,8 @@ #include "gdcmDictSet.h" #include "gdcmDocEntry.h" +class gdcmValEntry; +class gdcmBinEntry; class gdcmSeqEntry; #include "gdcmDocEntrySet.h" @@ -129,8 +131,11 @@ public: virtual bool WriteEntry(gdcmDocEntry *tag,FILE *_fp,FileType type); virtual bool WriteEntries(FILE *_fp,FileType type); - gdcmDocEntry * ReplaceOrCreateByNumber(std::string Value, + gdcmValEntry * ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem); + + gdcmBinEntry * ReplaceOrCreateByNumber(void *voidArea, int lgth, + guint16 Group, guint16 Elem); bool ReplaceIfExistByNumber (char *Value, guint16 Group, guint16 Elem); virtual void *LoadEntryVoidArea (guint16 Group, guint16 Element); @@ -166,6 +171,8 @@ protected: virtual bool SetEntryByName (std::string content, std::string tagName); virtual bool SetEntryByNumber(std::string content, guint16 group, guint16 element); + virtual bool SetEntryByNumber(void *content, int lgth, + guint16 group, guint16 element); virtual bool SetEntryLengthByNumber(guint32 length, guint16 group, guint16 element); @@ -178,6 +185,9 @@ protected: // Header entry gdcmDocEntry *GetDocEntryByNumber (guint16 group, guint16 element); gdcmDocEntry *GetDocEntryByName (std::string Name); + + gdcmValEntry *GetValEntryByNumber (guint16 group, guint16 element); + gdcmBinEntry *GetBinEntryByNumber (guint16 group, guint16 element); void LoadDocEntrySafe(gdcmDocEntry *); @@ -224,9 +234,13 @@ private: // DocEntry related utilities gdcmDocEntry *ReadNextDocEntry (void); gdcmDocEntry *NewDocEntryByNumber(guint16 group, - guint16 element); + guint16 element); gdcmDocEntry *NewDocEntryByName (std::string Name); - + + gdcmValEntry *NewValEntryByNumber(guint16 group, + guint16 element); + gdcmBinEntry *NewBinEntryByNumber(guint16 group, + guint16 element); guint32 GenerateFreeTagKeyInGroup(guint16 group); public: diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 5b89912c..288e53ce 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -779,7 +779,7 @@ bool gdcmFile::WriteBase (std::string fileName, FileType type) { } // ----------------- End of Special Patch ---------------- - fwrite(PixelData, lgrTotale, 1, fp1); + // fwrite(PixelData, lgrTotale, 1, fp1); // should be useless, now fclose (fp1); return(true); } diff --git a/src/gdcmSQItem.cxx b/src/gdcmSQItem.cxx index eda6b094..a3d51616 100644 --- a/src/gdcmSQItem.cxx +++ b/src/gdcmSQItem.cxx @@ -45,6 +45,7 @@ gdcmSQItem::~gdcmSQItem() for (int i=0;iSetPrintLevel(GetPrintLevel()); aurait-ce un sens ? + { + + std::cout << "SQItemNumber " << (*cc)->GetSQItemNumber() << std::endl; + (*cc)->Print(os); } // at end, print the sequence terminator item, if any if (delimitor_mode) { - s2 << " | " ; + s2 << " | " ; // FIXME : cout the right number of | ! os << s2.str(); if (seq_term != NULL) { seq_term->Print(os); @@ -83,7 +85,8 @@ void gdcmSeqEntry::Print(std::ostream &os){ // Public /// \brief adds the passed ITEM to the ITEM chained List for this SeQuence. -void gdcmSeqEntry::AddEntry(gdcmSQItem *sqItem) { +void gdcmSeqEntry::AddEntry(gdcmSQItem *sqItem, int itemNumber) { + sqItem->SetSQItemNumber(itemNumber); items.push_back(sqItem); } diff --git a/src/gdcmSeqEntry.h b/src/gdcmSeqEntry.h index 143e382b..91c373b4 100644 --- a/src/gdcmSeqEntry.h +++ b/src/gdcmSeqEntry.h @@ -29,7 +29,7 @@ public: /// \brief Sets the Sequence Delimitation Item inline void SetSequenceDelimitationItem(gdcmDocEntry * e) { seq_term = e;} - void AddEntry(gdcmSQItem *it); + void AddEntry(gdcmSQItem *it, int itemNumber); /// \brief creates a new SQITEM for this SeQuence. gdcmSQItem * NewItem(void); diff --git a/src/gdcmValEntry.cxx b/src/gdcmValEntry.cxx index a329b54c..656dd2a1 100644 --- a/src/gdcmValEntry.cxx +++ b/src/gdcmValEntry.cxx @@ -20,6 +20,23 @@ gdcmValEntry::gdcmValEntry(gdcmDictEntry* e) : gdcmDocEntry(e) { voidArea = NULL; // will be in BinEntry ? } +/** + * \ingroup gdcmValEntry + * \brief Constructor from a given gdcmDocEntry + * @param e Pointer to existing Doc entry + */ +gdcmValEntry::gdcmValEntry(gdcmDocEntry* e) : gdcmDocEntry(e->GetDictEntry()){ + this->UsableLength = e->GetLength(); + this->ReadLength = e->GetReadLength(); + this->ImplicitVR = e->IsImplicitVR(); + this->Offset = e->GetOffset(); + this->printLevel = e->GetPrintLevel(); + this->SQDepthLevel = e->GetDepthLevel(); + + this->voidArea = NULL; // will be in BinEntry ? +} + + /** * \brief Canonical destructor. */ diff --git a/src/gdcmValEntry.h b/src/gdcmValEntry.h index 5b199115..9a5912ba 100644 --- a/src/gdcmValEntry.h +++ b/src/gdcmValEntry.h @@ -18,7 +18,8 @@ class GDCM_EXPORT gdcmValEntry : public gdcmDocEntry { public: - gdcmValEntry(gdcmDictEntry* e); + gdcmValEntry(gdcmDictEntry* e); + gdcmValEntry(gdcmDocEntry* d); ~gdcmValEntry(void); /// \brief Returns the 'Value' (e.g. "Dupond Marcel") converted into a -- 2.48.1