// unsigned 16 bit integers in Dicom) expressed in hexadecimal.
// Example: consider the tag given as (group, element) = (0x0010, 0x0010).
// Then the corresponding TagKey shall be the string 0010|0010 (where
-// the | (pipe symbol) acts as a separator). Refer to
-// gdcmDictEntry::TranslateToKey for this conversion function.
+// the | (pipe symbol) acts as a separator).
+// Refer to gdcmDictEntry::TranslateToKey for this conversion function.
#include "gdcmException.h"
#include "gdcmCommon.h"
#pragma warning ( disable : 4284 )
#endif //_MSC_VER
+// Mmmmmm !
+// It reminds me the formerly well known LibIDO's idproto.h
+
#ifdef __GNUC__
#ifndef HAVE_NO_STDINT_H
#include <stdint.h>
/**
* \ingroup gdcmDict
- * \brief
+ * \brief Destructor
*/
gdcmDict::~gdcmDict() {
for (TagKeyHT::iterator tag = KeyHt.begin(); tag != KeyHt.end(); ++tag) {
}
/**
- * \ingroup gdcmDict
- * \brief
- * @param os
+ * \brief Print all the dictionary entries contained in this dictionary.
+ * Entries will be sorted by tag i.e. the couple (group, element).
+ * @param os The output stream to be written to.
*/
void gdcmDict::Print(std::ostream& os) {
PrintByKey(os);
* \ingroup gdcmDict
* \brief Print all the dictionary entries contained in this dictionary.
* Entries will be sorted by the name of the dictionary entries.
+ * \warning AVOID USING IT : the name IS NOT an identifier
+ * unpredictable result
* @param os The output stream to be written to.
*/
void gdcmDict::PrintByName(std::ostream& os) {
* \ingroup gdcmDict
* \brief Get the dictionnary entry identified by it's name.
* @param name element of the ElVal to modify
+ * \warning : NEVER use it !
+ * the 'name' IS NOT an identifier within the Dicom Dicom Dictionary
+ * the name MAY CHANGE between two versions !
* @return the corresponding dictionnary entry when existing, NULL otherwise
*/
gdcmDictEntry * gdcmDict::GetTagByName(TagName name) {
/**
* \ingroup gdcmDict
- * \brief
+ * \brief replaces an already existing Dicom Element by a new one
* @param NewEntry
- * @return
+ * @return false if Dicom Element doesn't exist
*/
-int gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
+bool gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
if ( RemoveEntry(NewEntry->gdcmDictEntry::GetKey()) ) {
KeyHt[ NewEntry->GetKey()] = NewEntry;
- return (1);
+ return (true);
}
- return (0);
+ return (false);
}
/**
* \ingroup gdcmDict
- * \brief
- * @param NewEntry
- * @return
+ * \brief adds a new Dicom Dictionary Entry
+ * @param NewEntry
+ * @return false if Dicom Element already existed
*/
- int gdcmDict::AddNewEntry(gdcmDictEntry* NewEntry) {
+ bool gdcmDict::AddNewEntry(gdcmDictEntry* NewEntry) {
TagKey key;
key = NewEntry->GetKey();
if(KeyHt.count(key) == 1) {
dbg.Verbose(1, "gdcmDict::AddNewEntry already present", key.c_str());
- return(0);
+ return(false);
} else {
KeyHt[NewEntry->GetKey()] = NewEntry;
- return(1);
+ return(true);
}
}
/**
* \ingroup gdcmDict
- * \brief
- * @param key
- * @return
+ * \brief removes an already existing Dicom Dictionary Entry,
+ * identified by its Tag
+ * @param key (group|element)
+ * @return false if Dicom Dictionary Entry doesn't exist
*/
-int gdcmDict::RemoveEntry(TagKey key) {
+bool gdcmDict::RemoveEntry(TagKey key) {
if(KeyHt.count(key) == 1) {
gdcmDictEntry* EntryToDelete = KeyHt.find(key)->second;
if ( EntryToDelete )
delete EntryToDelete;
KeyHt.erase(key);
- return (1);
+ return (true);
} else {
dbg.Verbose(1, "gdcmDict::RemoveEntry unfound entry", key.c_str());
- return (0);
+ return (false);
}
}
/**
* \ingroup gdcmDict
- * \brief
- * @param group
- * @param element
- * @return
+ * \brief removes an already existing Dicom Dictionary Entry,
+ * identified by its group,element
+ number
+ * @param group Dicom group number of the Dicom Element
+ * @param element Dicom element number of the Dicom Element
+ * @return false if Dicom Dictionary Entry doesn't exist
*/
-int gdcmDict::RemoveEntry (guint16 group, guint16 element) {
+bool gdcmDict::RemoveEntry (guint16 group, guint16 element) {
return( RemoveEntry(gdcmDictEntry::TranslateToKey(group, element)) );
}
public:
gdcmDict(std::string & FileName);
~gdcmDict();
- int AddNewEntry (gdcmDictEntry* NewEntry);
- int ReplaceEntry(gdcmDictEntry* NewEntry);
- int RemoveEntry (TagKey key);
- int RemoveEntry (guint16 group, guint16 element);
+ bool AddNewEntry (gdcmDictEntry* NewEntry);
+ bool ReplaceEntry(gdcmDictEntry* NewEntry);
+ bool RemoveEntry (TagKey key);
+ bool RemoveEntry (guint16 group, guint16 element);
gdcmDictEntry * GetTagByNumber(guint16 group, guint16 element);
gdcmDictEntry * GetTagByName(TagName name);
void Print(std::ostream&);
void PrintByKey(std::ostream&);
- void PrintByName(std::ostream&);
- TagKeyHT & GetEntries(void) { return KeyHt; }
+ void PrintByName(std::ostream&);
+
+ /**
+ * \ingroup gdcmDict
+ * \brief returns a ref to the Dicom Dictionary H table (map)
+ * return the Dicom Dictionary H table
+ */
+ inline TagKeyHT & gdcmDict::GetEntries(void) {
+ return KeyHt;
+ }
+
};
#endif
#include <stdio.h> // FIXME For sprintf
#include "gdcmUtil.h"
+/**
+ * \ingroup gdcmDictEntry
+ * \brief Construtor
+ * @param InGroup
+ * @param InElement
+ * @param InVr
+ * @param InFourth // DO NOT use any longer
+ * NOT part of the Dicom Standard
+ * @param InName
+*/
gdcmDictEntry::gdcmDictEntry(guint16 InGroup, guint16 InElement,
std::string InVr, std::string InFourth,
key = TranslateToKey(group, element);
}
+/**
+ * \ingroup gdcmDictEntry
+ * \brief concatenates 2 guint16 (supposed to be a Dicom group number
+ * and a Dicom element number)
+ * @param group the Dicom group number used to build the tag
+ * @param group the Dicom element number used to build the tag
+ * return the built tag
+ */
+
TagKey gdcmDictEntry::TranslateToKey(guint16 group, guint16 element) {
char trash[10];
TagKey key;
/**
* \ingroup gdcmDictEntry
- * \brief If-and only if-the vr is unset then overwrite it.
- * @param NewVr New vr to be set.
+ * \brief If-and only if-the V(alue) R(epresentation)
+ * is unset then overwrite it.
+ * @param NewVr New V(alue) R(epresentation) to be set.
*/
void gdcmDictEntry::SetVR(std::string NewVr) {
if ( IsVrUnknown() )
"Overwriting vr might compromise a dictionary");
}
}
-
-bool gdcmDictEntry::IsVrUnknown() {
- if ( vr == "Unknown" )
- return true;
- return false;
-}
std::string vr = "Unknown",
std::string fourth = "Unknown",
std::string name = "Unknown");
-
- // fabrique une 'clé' par concaténation du numGroupe et du numElement
-
- // Pourquoi fait-elle partie de DictEntry?
- // elle pourrait etre utilisée egalement ailleurs, hors tout Dictionnaire
-
- // Pourquoi 'static'?
static TagKey TranslateToKey(guint16 group, guint16 element);
+
+// bool IsVrUnknown(void);
- guint16 GetGroup(void) {return group; };
- guint16 GetElement(void){return element;};
- std::string GetVR(void) {return vr; };
- void SetVR(std::string);
- void SetKey(std::string k){ key = k; };
- bool IsVrUnknown(void);
- std::string GetFourth(void) {return fourth;};
- std::string GetName(void) {return name; };
- std::string GetKey(void) {return key; };
+// inline guint16 GetGroup(void);
+// inline guint16 GetElement(void);
+// inline std::string GetVR(void);
+ void SetVR(std::string);
+// inline void SetKey(std::string k);
+// inline std::string GetFourth(void);
+// inline std::string GetName(void);
+// inline std::string GetKey(void);
+
+
+
+/**
+ * \ingroup gdcmDictEntry
+ * \brief tells if the V(alue) R(epresentation) is known (?!)
+ *
+ * @return
+ */
+inline bool gdcmDictEntry::IsVrUnknown() {
+ if ( vr == "Unknown" )
+ return true;
+ return false;
+}
+
+
+/**
+ * \ingroup gdcmDictEntry
+ * \brief returns the Dicom Group Number of the current gdcmDictEntry
+ * return the Dicom Group Number
+ */
+ inline guint16 gdcmDictEntry::GetGroup(void) {
+ return group;
+ }
+
+/**
+ * \ingroup gdcmDictEntry
+ * \brief returns the Dicom Element Number of the current gdcmDictEntry
+ * return the Dicom Element Number
+ */
+ inline guint16 gdcmDictEntry::GetElement(void) {
+ return element;
+ }
+
+ /**
+ * \ingroup gdcmDictEntry
+ * \brief returns the Dicom Value Representation of the current gdcmDictEntry
+ * return the Dicom Value Representation
+ */
+ inline std::string gdcmDictEntry::GetVR(void) {
+ return vr;
+ }
+
+/**
+ * \ingroup gdcmDictEntry
+ * \brief sets the key of the current gdcmDictEntry
+ * @param k New key to be set.
+ */
+ inline void gdcmDictEntry::SetKey(std::string k) {
+ key = k;
+ }
+
+ /**
+ * \ingroup gdcmDictEntry
+ * \brief returns the Fourth field of the current gdcmDictEntry
+ * \warning NOT part of the Dicom Standard
+ * \ May be REMOVED an any time
+ * \ NEVER use it
+ * return the Fourth field
+ */
+ inline std::string gdcmDictEntry::GetFourth(void) {
+ return fourth;
+ }
+
+ /**
+ * \ingroup gdcmDictEntry
+ * \brief returns the Dicom Name of the current gdcmDictEntry
+ * \ e.g. "Patient Name" for Dicom Tag (0x0010, 0x0010)
+ * return the Dicom Name
+ */
+ inline std::string gdcmDictEntry::GetName(void) {
+ return name;
+ }
+
+ /**
+ * \ingroup gdcmDictEntry
+ * \brief Gets the key of the current gdcmDictEntry
+ * @return the key .
+ */
+ inline std::string gdcmDictEntry::GetKey(void) {
+ return key;
+ }
+
+
};
#endif
* A typical usage of this method would be to enable a dynamic
* configuration of a Dicom file browser: the admin/user can
* select in the interface which Dicom tags should be displayed.
+
* \warning Dicom *doesn't* define any name for any 'categorie'
* (the dictionnary fourth field was formerly NIH defined
* - and no longer he is-
* and will be removed when Dicom provides us a text file
* with the 'official' Dictionnary, that would be more friendly
- * than asking us to perform a line by line check od thhe dictionnary
+ * than asking us to perform a line by line check of the dictionnary
* at the beginning of each year to -try to- guess the changes)
* Therefore : please NEVER use that fourth field :-(
- *
+ * *
* @return An hashtable: whose keys are the names of the groups and whose
* corresponding values are lists of all the dictionnary entries
* among that group.
* path to directory containing the dictionnaries. When
* the environnement variable is absent the path is defaulted
* to "../Dicts/".
+ * @return path to directory containing the dictionnaries
*/
std::string gdcmDictSet::BuildDictPath(void) {
std::string ResultPath;
Dicts[PUB_DICT_NAME] = new gdcmDict(PubDictFile);
}
+
+/**
+ * \ingroup gdcmDictSet
+ * \brief Destructor
+ */
gdcmDictSet::~gdcmDictSet() {
for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) {
gdcmDict* EntryToDelete = tag->second;
* \ingroup gdcmDictSet
* \brief Retrieve the specified dictionary (when existing) from this
* gdcmDictSet.
- * @param DictName The synbolic name of the searched dictionary.
+ * @param DictName The symbolic name of the searched dictionary.
* \result The retrieved dictionary.
*/
gdcmDict * gdcmDictSet::GetDict(DictKey DictName) {
# include <sstream>
#endif
-
+/**
+ * \ingroup gdcmElValSet
+ * \brief Destructor
+ */
gdcmElValSet::~gdcmElValSet() {
for (TagElValueHT::iterator tag = tagHt.begin(); tag != tagHt.end(); ++tag) {
gdcmElValue* EntryToDelete = tag->second;
}
tagHt.clear();
- // Since Add() adds symetrical in both tagHt and NameHt we can
- // assume all the pointed gdcmElValues are already cleaned-up when
- // we cleaned tagHt.
- NameHt.clear();
}
/**
* \ingroup gdcmElValSet
- * \brief
+ * \brief add a new Dicom Element pointer to
+ * the H Table and to the chained List
* @param newElValue
- * @return
*/
void gdcmElValSet::Add(gdcmElValue * newElValue) {
- tagHt [newElValue->GetKey()] = newElValue;
- NameHt[newElValue->GetName()] = newElValue;
+
+// tagHt [newElValue->GetKey()] = newElValue;
+
+ tagHt.insert( PairHT( newElValue->GetKey(),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);
+ listElem.push_back(newElValue);
}
/**
* \ingroup gdcmElValSet
- * \brief Checks if a given Dicom element exists
- * \ within a ElValSet
- * @param Group
- * @param Elem
- * @return
+ * \brief Checks if a given Dicom Element exists
+ * \ within the H table
+ * @param Group Group number of the searched Dicom Element
+ * @param Elem Element number of the searched Dicom Element
+ * @return number of occurences
*/
int gdcmElValSet::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
std::string key = TranslateToKey(Group, Elem );
/**
* \ingroup gdcmElValSet
- * \brief
+ * \brief prints the Dicom Elements of the gdcmHeader
+ * using both H table and Chained List
+ * @param os The output stream to be written to.
*/
void gdcmElValSet::Print(std::ostream & os) {
TSKey v;
std::string d2;
gdcmTS * ts = gdcmGlobal::GetTS();
+
+ std::cout << "------------- using tagHt ---------------------" << std::endl;
+ // Do not remove cout
std::ostringstream s;
for (TagElValueHT::iterator tag = tagHt.begin();
guint32 lgth;
char greltag[10]; //group element tag
+ std::cout << "------------ using listElem -------------------" << std::endl;
+ // Do not remove cout
+
for (ListTag::iterator i = listElem.begin();
i != listElem.end();
++i){
/**
* \ingroup gdcmElValSet
- * \brief
- */
-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() << "]" << std::endl;
- }
-}
-
-/**
- * \ingroup gdcmElValSet
- * \brief
- * @param group
- * @param element
+ * \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 elem Element number of the searched Dicom Element
* @return
*/
gdcmElValue* gdcmElValSet::GetElementByNumber(guint16 group, guint16 element) {
/**
* \ingroup gdcmElValSet
- * \brief
- * @return
- */
-gdcmElValue* gdcmElValSet::GetElementByName(std::string TagName) {
- if ( ! NameHt.count(TagName))
- return (gdcmElValue*)0;
- return NameHt.find(TagName)->second;
-}
-
-/**
- * \ingroup gdcmElValSet
- * \brief
- * @param group
- * @param element
+ * \brief Gets the value (string) of the target Dicom Element
+ * @param group Group number of the searched Dicom Element
+ * @param elem Element number of the searched Dicom Element
* @return
*/
std::string gdcmElValSet::GetElValueByNumber(guint16 group, guint16 element) {
return tagHt.find(key)->second->GetValue();
}
-/**
- * \ingroup gdcmElValSet
- * \brief
- * @return
- */
-std::string gdcmElValSet::GetElValueByName(std::string TagName) {
- if ( ! NameHt.count(TagName))
- return GDCM_UNFOUND;
- return NameHt.find(TagName)->second->GetValue();
-}
/**
* \ingroup gdcmElValSet
- * \brief
- * @param content
- * @param group
- * @param element
+ * \brief Sets the value (string) of the target Dicom Element
+ * @param content string value of the Dicom Element
+ * @param group Group number of the searched Dicom Element
+ * @param elem Element number of the searched Dicom Element
* @return
*/
-int gdcmElValSet::SetElValueByNumber(std::string content,
+bool gdcmElValSet::SetElValueByNumber(std::string content,
guint16 group, guint16 element) {
TagKey key = gdcmDictEntry::TranslateToKey(group, element);
if ( ! tagHt.count(key))
- return 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);
-
- std::string vr = tagHt[key]->GetVR();
+
+ //tagHt[key]->SetValue(content);
+ gdcmElValue * a;
+ IterHT p;
+ TagElValueHT::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);
- return 1;
+ //tagHt[key]->SetLength(lgr);
+ a->SetLength(lgr);
+ return true;
}
-/**
- * \ingroup gdcmElValSet
- * \brief
- * @param content
- * @param TagName
- * @return
- */
-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);
-
- std::string vr = NameHt[TagName]->GetVR();
- guint32 lgr;
-
- if( (vr == "US") || (vr == "SS") )
- lgr = 2;
- else if( (vr == "UL") || (vr == "SL") )
- lgr = 4;
- else
- lgr = content.length();
-
-// TODO : WARNING: le cas de l'element des pixels (7fe0,0010) n'est pas traite
-// par SetElValueByName
-// il faudra utiliser SetElValueByNumber
-
- NameHt[TagName]->SetLength(lgr);
- return 1;
-}
/**
* \ingroup gdcmElValSet
/**
* \ingroup gdcmElValSet
- * \brief
+ * \brief Sets a 'non string' value to a given Dicom Element
* @param area
- * @param group
- * @param element
+ * @param group Group number of the searched Dicom Element
+ * @param elem Element number of the searched Dicom Element
* @return
*/
-int gdcmElValSet::SetVoidAreaByNumber(void * area,
+bool gdcmElValSet::SetVoidAreaByNumber(void * area,
guint16 group, guint16 element) {
TagKey key = gdcmDictEntry::TranslateToKey(group, element);
if ( ! tagHt.count(key))
- return 0;
- tagHt[key]->SetVoidArea(area);
- return 1 ;
+ return false;
+ //tagHt[key]->SetVoidArea(area);
+ ( ((tagHt.equal_range(key)).first)->second )->SetVoidArea(area);
+ return true ;
}
/**
* \ingroup gdcmElValSet
- * \brief
+ * \brief Sets the value length of the Dicom Element
+ * \warning : use with caution !
* @param length
- * @param group
- * @param element
- * @return int acts as a boolean
+ * @param group Group number of the searched Dicom Element
+ * @param elem Element number of the searched Dicom Element
+ * @return boolean
*/
-int gdcmElValSet::SetElValueLengthByNumber(guint32 length,
+bool gdcmElValSet::SetElValueLengthByNumber(guint32 length,
guint16 group, guint16 element) {
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 ;
-}
-/**
- * \ingroup gdcmElValSet
- * \brief
- * @param length
- * @param TagName
- * @return
- */
-int gdcmElValSet::SetElValueLengthByName(guint32 length, std::string TagName) {
- if ( ! NameHt.count(TagName))
- return 0;
+ return false;
if (length%2) length++; // length must be even
- NameHt.find(TagName)->second->SetLength(length);
- return 1 ;
+ //tagHt[key]->SetLength(length);
+ ( ((tagHt.equal_range(key)).first)->second )->SetLength(length);
+
+ return true ;
}
+
+// ==============
+// TODO to be re-written using the chained list instead of the H table
+// so we can remove the GroupHT from the gdcmHeader
+// =============
+
/**
* \ingroup gdcmElValSet
* \brief Re-computes the length of a ACR-NEMA/Dicom group from a DcmHeader
+ * \warning : to be re-written using the chained list instead of the H table.
+ * \todo : to be re-written using the chained list instead of the H table
* @param SkipSequence TRUE if we don't want to write Sequences (ACR-NEMA Files)
- * @param type
+ * @param type Type of the File (ExplicitVR,ImplicitVR, ACR, ...)
*/
void gdcmElValSet::UpdateGroupLength(bool SkipSequence, FileType type) {
guint16 gr, el;
/**
* \ingroup gdcmElValSet
* \brief writes on disc according to the requested format
- * \ (ACR-NEMA, DICOM, RAW) the image
+ * \ (ACR-NEMA, ExplicitVR, ImplicitVR) 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)
+ * (ACR-NEMA, ExplicitVR, ImplicitVR)
* @param _fp already open file pointer
* @return
*/
if (gr < 0x0008) continue; // ignore pure DICOM V3 groups
if (gr %2) continue; // ignore shadow groups
if (vr == "SQ" ) continue; // ignore Sequences
+ // TODO : find a trick to *skip* the SeQuences !
+ // Not only ignore the SQ element
if (gr == 0xfffe ) continue; // ignore delimiters
}
/**
* \ingroup gdcmElValSet
* \brief
- * @param _fp
- * @param type
- * @return
+ * @param _fp already open file pointer
+ * @param type type of the File to be written
+ * (ACR-NEMA, ExplicitVR, ImplicitVR)
+ * @return always "True" ?!
*/
-int gdcmElValSet::Write(FILE * _fp, FileType type) {
+bool gdcmElValSet::Write(FILE * _fp, FileType type) {
// Question :
// Comment pourrait-on savoir si le DcmHeader vient d'un fichier DicomV3 ou non
UpdateGroupLength(true,ACR);
WriteElements(type, _fp);
- return(1);
+ return(true);
}
+
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.20 2004/01/12 13:12:28 regrain Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.21 2004/01/13 11:32:30 jpr Exp $
#ifndef GDCMELVALSET_H
#define GDCMELVALSET_H
#include <list> // for linking together *all* the Dicom Elements
/*
- * Container for a set of successfully parsed ElValues.
+ * Container for a set of successfully parsed ElValues (i.e. Dicom Elements).
*/
-typedef std::map<TagKey, gdcmElValue*> TagElValueHT;
-typedef std::map<std::string, gdcmElValue*> TagElValueNameHT;
-
+
+typedef std::multimap<TagKey, gdcmElValue*> TagElValueHT;
+typedef std::pair<TagKey, gdcmElValue*> PairHT;
+typedef std::pair<TagElValueHT::iterator,TagElValueHT::iterator> IterHT;
+
+typedef std::list<gdcmElValue*> ListTag; // for linking together the Elements
+
+// TODO : to be removed after re-writting gdcmElValSet::UpdateGroupLength
+// using the chained list instead of the H table
typedef std::string GroupKey;
typedef std::map<GroupKey, int> GroupHT;
-typedef std::list<gdcmElValue*> ListTag; // for linking together the Elements
class GDCM_EXPORT gdcmElValSet {
- TagElValueHT tagHt; // Both accesses with a TagKey or with a
- TagElValueNameHT NameHt; // the DictEntry.Name are required.
- ListTag listElem;
+ TagElValueHT tagHt; // H Table (multimap), to provide fast access
+ ListTag listElem; // chained list, to keep the 'spacial' ordering
public:
~gdcmElValSet();
void Add(gdcmElValue*);
void Print(std::ostream &);
- void PrintByName(std::ostream &);
- int Write(FILE *fp, FileType type);
+ bool Write(FILE *fp, FileType type);
gdcmElValue* GetElementByNumber(guint16 group, guint16 element);
- gdcmElValue* GetElementByName (std::string);
+ //gdcmElValue* GetElementByName (std::string);
+ // moved to gdcmHeader
std::string GetElValueByNumber(guint16 group, guint16 element);
- std::string GetElValueByName (std::string);
-
- TagElValueHT & GetTagHt(void) {return tagHt;};
- ListTag & GetListElem(void) {return listElem;};
- int SetElValueByNumber(std::string content, guint16 group, guint16 element);
- int SetElValueByName (std::string content, std::string TagName);
+ bool SetElValueByNumber(std::string content, guint16 group, guint16 element);
+ // bool SetElValueByName (std::string content, std::string TagName);
+ // moved to gdcmHeader
- int SetElValueLengthByNumber(guint32 l, guint16 group, guint16 element);
- int SetElValueLengthByName (guint32 l, std::string TagName);
+ bool SetElValueLengthByNumber(guint32 l, guint16 group, guint16 element);
- int SetVoidAreaByNumber(void *a, guint16 Group, guint16 Elem );
+ bool SetVoidAreaByNumber(void *a, guint16 Group, guint16 Elem );
guint32 GenerateFreeTagKeyInGroup(guint16 group);
- int CheckIfExistByNumber(guint16 Group, guint16 Elem );
-
+ int CheckIfExistByNumber(guint16 Group, guint16 Elem ); // int !
+
+ /**
+ * \ingroup gdcmElValSet
+ * \brief returns a ref to the Dicom Header H table (multimap)
+ * return the Dicom Header H table
+ */
+inline TagElValueHT & gdcmElValSet::GetTagHt(void) {
+ return tagHt;
+ };
+
+ /**
+ * \ingroup gdcmElValSet
+ * \brief returns a ref to the Dicom Header chained list
+ * return the Dicom Header chained list
+ */
+ inline ListTag & gdcmElValSet::GetListElem(void) {
+ return listElem;
+ };
+
private:
void UpdateGroupLength(bool SkipSequence = false, FileType type = ImplicitVR);
void WriteElements(FileType type, FILE *);
+
+
};
#endif
// gdcmElValue.cxx
-#include "gdcmElValue.h"
+// TODO
+// A 'gdcmElValue' is actually a 'Dicom Element'.
+// WHY such a confusing name???
+//
+#include "gdcmElValue.h"
/**
* \ingroup gdcmElValue
ImplicitVr = false;
entry = in;
}
+
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValue.h,v 1.10 2004/01/12 13:12:28 regrain Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmElValue.h,v 1.11 2004/01/13 11:32:30 jpr Exp $
#ifndef GDCMELVALUE_H
#define GDCMELVALUE_H
// going on.
// *for internal* use only
- bool ImplicitVr; // Even when reading explicit vr files, some
+ bool ImplicitVr; // Even when reading explicit vr files, some
// elements happen to be implicit. Flag them here
// since we can't use the entry->vr without breaking
// the underlying dictionary.
- void SetOffset(size_t of){ Offset = of; };
-
// FIXME: In fact we should be more specific and use :
// friend gdcmElValue * gdcmHeader::ReadNextElement(void);
friend class gdcmHeader;
size_t Offset; // Offset from the begining of file for direct user access
gdcmElValue(gdcmDictEntry*);
- void SetDictEntry(gdcmDictEntry *NewEntry) { entry = NewEntry; };
- bool IsVrUnknown(void) { return entry->IsVrUnknown(); };
- void SetImplicitVr(void) { ImplicitVr = true; };
- bool IsImplicitVr(void) { return ImplicitVr; };
-
- gdcmDictEntry * GetDictEntry(void) { return entry; };
- guint16 GetGroup(void) { return entry->GetGroup(); };
- guint16 GetElement(void) { return entry->GetElement();};
- std::string GetKey(void) { return entry->GetKey(); };
- std::string GetName(void) { return entry->GetName(); };
- std::string GetVR(void) { return entry->GetVR(); };
- std::string GetValue(void) { return value; };
- void * GetVoidArea(void) { return voidArea; };
- size_t GetOffset(void) { return Offset; };
- guint32 GetLength(void) { return UsableLength; };
- // for internal use only!
- guint32 GetReadLength(void){ return ReadLength; };
+ // inline void SetDictEntry(gdcmDictEntry *NewEntry);
+ // inline bool IsVrUnknown(void);
+ // inline void SetImplicitVr(void);
+ // inline bool IsImplicitVr(void);
+ // inline void SetOffset(size_t of);
+ // inline gdcmDictEntry * GetDictEntry(void);
- void SetVR(std::string v) { entry->SetVR(v); };
- void SetLength(guint32 l) { ReadLength=UsableLength=l;};
- // The following 2 members, for internal use only !
- void SetReadLength(guint32 l) { ReadLength = l; };
- void SetUsableLength(guint32 l){ UsableLength = l; };
+ inline guint16 GetGroup(void) { return entry->GetGroup(); };
+ inline guint16 GetElement(void) { return entry->GetElement();};
+ inline std::string GetKey(void) { return entry->GetKey(); };
+ inline std::string GetName(void) { return entry->GetName(); };
+ inline std::string GetVR(void) { return entry->GetVR(); };
+ inline std::string GetValue(void) { return value; };
+ inline void * GetVoidArea(void) { return voidArea; };
+ inline size_t GetOffset(void) { return Offset; };
+ inline guint32 GetLength(void) { return UsableLength; };
+ inline void SetVR(std::string v) { entry->SetVR(v); };
+ inline void SetLength(guint32 l) { ReadLength=UsableLength=l;};
+
+ // The following 3 members, for internal use only !
+ inline void SetReadLength(guint32 l) { ReadLength = l; };
+ inline void SetUsableLength(guint32 l){ UsableLength = l; };
+ inline guint32 GetReadLength(void) { return ReadLength;};
- void SetValue(std::string val) { value = val; };
- void SetVoidArea(void * area) { voidArea = area; };
+ inline void SetValue(std::string val) { value = val; };
+ inline void SetVoidArea(void * area) { voidArea = area; };
+
+
+
+/**
+ * \ingroup gdcmElValue
+ * \brief Sets the offset of the Dicom Element
+ * \warning : use with caution !
+ * @param of offset to be set
+ */
+
+inline void gdcmElValue::SetOffset(size_t of){
+ Offset = of;
+};
+
+/**
+ * \ingroup gdcmElValue
+ * \brief Sets the DicEntry of the current Dicom Element
+ * @param NewEntry pointer to the DictEntry
+ */
+
+inline void gdcmElValue::SetDictEntry(gdcmDictEntry *NewEntry) {
+ entry = NewEntry;
+};
+
+/**
+ * \ingroup gdcmElValue
+ * \brief tells us if the VR of the current Dicom Element is Unkonwn
+ * @return true if the VR is unkonwn
+ */
+
+inline bool gdcmElValue::IsVrUnknown(void) {
+ return entry->IsVrUnknown();
+};
+
+/**
+ * \ingroup gdcmElValue
+ * \brief Sets to TRUE the ImplicitVr flag of the current Dicom Element
+ */
+
+inline void gdcmElValue::SetImplicitVr(void) {
+ ImplicitVr = true;
+};
+
+/**
+ * \ingroup gdcmElValue
+ * \brief tells us if the current Dicom Element was checked as ImplicitVr
+ * @return true if the current Dicom Element was checked as ImplicitVr
+ */
+inline bool gdcmElValue::IsImplicitVr(void) {
+ return ImplicitVr;
+ };
+
+/**
+ * \ingroup gdcmElValue
+ * \brief Gets the DicEntry of the current Dicom Element
+ * @return the DicEntry of the current Dicom Element
+ */
+gdcmDictEntry * gdcmElValue::GetDictEntry(void) {
+ return entry;
+};
+
};
* for DICOM compliance. Returns NULL on failure.
* \Note If the gdcmHeader is created by the gdcmFile, it is destroyed
* by the gdcmFile
- *
- * @param filename file to be opened for parsing
- *
- * @return
+ * *
*/
gdcmFile::~gdcmFile(void)
{
*
* @return integer acts as a boolean
*/
-int gdcmFile::SetImageData(void * inData, size_t ExpectedSize) {
+bool gdcmFile::SetImageData(void * inData, size_t ExpectedSize) {
Header->SetImageDataSize(ExpectedSize);
PixelData = inData;
lgrTotale = ExpectedSize;
- return(1);
+ return(true);
}
* @return
*/
-int gdcmFile::WriteRawData (std::string fileName) {
+bool gdcmFile::WriteRawData (std::string fileName) {
FILE * fp1;
fp1 = fopen(fileName.c_str(),"wb");
if (fp1 == NULL) {
printf("Echec ouverture (ecriture) Fichier [%s] \n",fileName.c_str());
- return (0);
+ return (false);
}
fwrite (PixelData,lgrTotale, 1, fp1);
fclose (fp1);
- return(1);
+ return(true);
}
/////////////////////////////////////////////////////////////////
* @return int acts as a boolean
*/
-int gdcmFile::WriteDcmImplVR (std::string fileName) {
+bool gdcmFile::WriteDcmImplVR (std::string fileName) {
return WriteBase(fileName, ImplicitVR);
}
* @return int acts as a boolean
*/
-int gdcmFile::WriteDcmImplVR (const char* fileName) {
+bool gdcmFile::WriteDcmImplVR (const char* fileName) {
return WriteDcmImplVR (std::string (fileName));
}
* @return int acts as a boolean
*/
-int gdcmFile::WriteDcmExplVR (std::string fileName) {
+bool gdcmFile::WriteDcmExplVR (std::string fileName) {
return WriteBase(fileName, ExplicitVR);
}
* @return int acts as a boolean
*/
-int gdcmFile::WriteAcr (std::string fileName) {
+bool gdcmFile::WriteAcr (std::string fileName) {
return WriteBase(fileName, ACR);
}
*
* @return int acts as a boolean
*/
-int gdcmFile::WriteBase (std::string FileName, FileType type) {
+bool gdcmFile::WriteBase (std::string FileName, FileType type) {
FILE * fp1;
fp1 = fopen(FileName.c_str(),"wb");
if (fp1 == NULL) {
printf("Echec ouverture (ecriture) Fichier [%s] \n",FileName.c_str());
- return (0);
+ return (false);
}
if ( (type == ImplicitVR) || (type == ExplicitVR) ) {
fwrite(PixelData, lgrTotale, 1, fp1);
fclose (fp1);
- return(1);
+ return(true);
}
bool gdcm_read_RLE_file (FILE *fp,void * image_buffer);
protected:
- int WriteBase(std::string FileName, FileType type);
+ bool WriteBase(std::string FileName, FileType type);
public:
gdcmFile(gdcmHeader *header);
// On writing purposes. When instance was created through
// gdcmFile(std::string filename) then the filename argument MUST be
- // different from the constructor's one (no overwriting allowed).
+ // different from the constructor's one (no overwriting allowed).
// TODO Swig int SetFileName(std::string filename);
void SetPixelDataSizeFromHeader(void);
// the caller might destroy it's image (without knowing it: think
// of a complicated interface where display is done with a library
// e.g. VTK) before calling the Write
- int SetImageData (void * Data, size_t ExpectedSize);
+
+ // voir gdcmHeader::SetImageDataSize ?!?
+ bool SetImageData (void * Data, size_t ExpectedSize);
// When the caller is aware we simply point to the data:
// TODO int SetImageDataNoCopy (void * Data, size_t ExpectedSize);
// Ecrit sur disque les pixels d'UNE image
// Aucun test n'est fait sur l'"Endiannerie" du processeur.
// Ca sera à l'utilisateur d'appeler son Reader correctement
- int WriteRawData (std::string fileName);
- int WriteDcmImplVR(std::string fileName);
- int WriteDcmImplVR(const char * fileName);
- int WriteDcmExplVR(std::string fileName);
- int WriteAcr (std::string fileName);
+
+ bool WriteRawData (std::string fileName);
+ bool WriteDcmImplVR(std::string fileName);
+ bool WriteDcmImplVR(const char * fileName);
+ bool WriteDcmExplVR(std::string fileName);
+ bool WriteAcr (std::string fileName);
bool ParsePixelData(void);
};
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.122 2004/01/13 11:13:08 regrain Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.123 2004/01/13 11:32:30 jpr Exp $
#include "gdcmHeader.h"
* \brief
* @param InFilename
* @param exception_on_error
+ * @param enable_sequences = true to allow the header
+ * to be parsed *inside* the SeQuences,
+ * when they have an actual length
+ the
*/
gdcmHeader::gdcmHeader(const char *InFilename,
bool exception_on_error,
if (x==ntohs(x))
net2host = true;
else
- net2host = false;
-
+ 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);
* @param Elem
* \return integer acts as a boolean
*/
-int gdcmHeader::ReplaceOrCreateByNumber(std::string Value,
+bool gdcmHeader::ReplaceOrCreateByNumber(std::string Value,
guint16 Group, guint16 Elem ) {
// TODO : FIXME JPRx
// curieux, non ?
if (CheckIfExistByNumber(Group, Elem) == 0) {
gdcmElValue* a =NewElValueByNumber(Group, Elem);
if (a == NULL)
- return 0;
+ return false;
PubElValSet.Add(a);
}
PubElValSet.SetElValueByNumber(Value, Group, Elem);
- return(1);
+ return(true);
}
* \return integer acts as a boolean
*
*/
-int gdcmHeader::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) {
+bool gdcmHeader::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) {
gdcmElValue* nvElValue=NewElValueByNumber(Group, Elem);
+ // TODO : check if fails
PubElValSet.Add(nvElValue);
std::string v = Value;
PubElValSet.SetElValueByNumber(v, Group, Elem);
- return(1);
+ return(true);
}
* @param Elem
* \return integer acts as a boolean
*/
-int gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) {
+bool gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) {
//gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
std::string v = Value;
PubElValSet.SetElValueByNumber(v, Group, Elem);
- return 1;
+ return true;
}
* @return integer acts as a boolean
*/
-int gdcmHeader::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
+bool gdcmHeader::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
return (PubElValSet.CheckIfExistByNumber(Group, Elem));
}
*/
bool gdcmHeader::IsAnInteger(gdcmElValue * ElVal) {
guint16 element = ElVal->GetElement();
+ guint16 group = ElVal->GetGroup();
std::string vr = ElVal->GetVR();
guint32 length = ElVal->GetLength();
+ cout << "Found :" << std::hex
+ << group << " , " << element << std::endl;
+
// 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 (length == 4)
return true;
else {
+ cout << "Error on :" << std::hex
+ << group << " , " << element << std::endl;
dbg.Error("gdcmHeader::IsAnInteger",
"Erroneous Group Length element length.");
}
// When the "Image Location" is absent we default to group 0x7fe0.
guint16 grPixel;
guint16 numPixel;
- std::string ImageLocation = GetPubElValByName("Image Location");
- if ( ImageLocation == GDCM_UNFOUND ) {
+ std::string ImageLocation = GetPubElValByNumber(0x0028, 0x0200);
+ if ( ImageLocation == GDCM_UNFOUND ) { // Image Location
grPixel = 0x7fe0;
} else {
grPixel = (guint16) atoi( ImageLocation.c_str() );
// When the "Image Location" is absent we default to group 0x7fe0.
guint16 grPixel;
guint16 numPixel;
- std::string ImageLocation = GetPubElValByName("Image Location");
+ std::string ImageLocation = GetPubElValByNumber(0x0028, 0x0200);
if ( ImageLocation == GDCM_UNFOUND ) {
grPixel = 0x7fe0;
} else {
* \ingroup gdcmHeader
* \brief Searches within the public dictionary for element value of
* a given tag.
- * @param TagName name of the searched element.
+ * @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::GetPubElValByName(std::string TagName) {
- return PubElValSet.GetElValueByName(TagName);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Searches within the elements parsed with the public dictionary 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::GetPubElValRepByName(std::string TagName) {
- gdcmElValue* elem = PubElValSet.GetElementByName(TagName);
- if ( !elem )
+std::string gdcmHeader::GetPubElValByName(std::string tagName) {
+ gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName);
+ if( dictEntry == NULL)
return GDCM_UNFOUND;
- return elem->GetVR();
+ return(PubElValSet.GetElValueByNumber(dictEntry->GetGroup(),
+ dictEntry->GetElement()));
}
/**
* \ingroup gdcmHeader
- * \brief Searches within elements parsed with the SHADOW dictionary
- * for the element value 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::GetShaElValByNumber(guint16 group, guint16 element) {
- return ShaElValSet.GetElValueByNumber(group, element);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Searches within the elements parsed with the SHADOW dictionary
- * 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::GetShaElValRepByNumber(guint16 group, guint16 element) {
- gdcmElValue* elem = ShaElValSet.GetElementByNumber(group, element);
- if ( !elem )
- return GDCM_UNFOUND;
- return elem->GetVR();
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Searches within the elements parsed with the shadow dictionary
- * for an element value of given tag.
- * @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::GetShaElValByName(std::string TagName) {
- return ShaElValSet.GetElValueByName(TagName);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Searches within the elements parsed with the shadow dictionary for
+ * \brief Searches within the elements parsed with the public dictionary 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.
+ * @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::GetShaElValRepByName(std::string TagName) {
- gdcmElValue* elem = ShaElValSet.GetElementByName(TagName);
- if ( !elem )
- return GDCM_UNFOUND;
+std::string gdcmHeader::GetPubElValRepByName(std::string tagName) {
+ gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName);
+ if( dictEntry == NULL)
+ return GDCM_UNFOUND;
+ gdcmElValue* elem = PubElValSet.GetElementByNumber(
+ dictEntry->GetGroup(),
+ dictEntry->GetElement());
return elem->GetVR();
}
*/
std::string gdcmHeader::GetElValByNumber(guint16 group, guint16 element) {
std::string pub = GetPubElValByNumber(group, element);
- if (pub.length())
return pub;
- return GetShaElValByNumber(group, element);
}
/**
*/
std::string gdcmHeader::GetElValRepByNumber(guint16 group, guint16 element) {
std::string pub = GetPubElValRepByNumber(group, element);
- if (pub.length())
return pub;
- return GetShaElValRepByNumber(group, element);
}
/**
* \brief Searches within elements parsed with the public dictionary
* and then within the elements parsed with the shadow dictionary
* for the element value of a given tag.
- * @param TagName name of the searched element.
+ * @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::GetElValByName(std::string TagName) {
- std::string pub = GetPubElValByName(TagName);
- if (pub.length())
+std::string gdcmHeader::GetElValByName(std::string tagName) {
+ std::string pub = GetPubElValByName(tagName);
return pub;
- return GetShaElValByName(TagName);
}
/**
* 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.
+ * @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::GetElValRepByName(std::string TagName) {
- std::string pub = GetPubElValRepByName(TagName);
- if (pub.length())
+std::string gdcmHeader::GetElValRepByName(std::string tagName) {
+ std::string pub = GetPubElValRepByName(tagName);
return pub;
- return GetShaElValRepByName(TagName);
}
/**
* \ingroup gdcmHeader
- * \brief Accesses an existing gdcmElValue in the PubElValSet of this instance
+ * \brief Accesses an existing gdcmElValue (i.e. a Dicom Element)
+ * in the PubElValSet of this instance
* 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 ElVal to modify
- * @param element element of the ElVal to modify
+ * @param group group of the Dicom Element to modify
+ * @param element element of the Dicom Element to modify
*/
-int gdcmHeader::SetPubElValByNumber(std::string content, guint16 group,
+bool gdcmHeader::SetPubElValByNumber(std::string content, guint16 group,
guint16 element)
//TODO : homogeneiser les noms : SetPubElValByNumber
// qui appelle PubElValSet.SetElValueByNumber
// pourquoi pas SetPubElValueByNumber ??
{
-
return ( PubElValSet.SetElValueByNumber (content, group, element) );
}
* \brief Accesses an existing gdcmElValue in the PubElValSet 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 tag to be modified
+ * @param tagName name of the tag to be modified
*/
-int gdcmHeader::SetPubElValByName(std::string content, std::string TagName) {
- return ( PubElValSet.SetElValueByName (content, TagName) );
+bool gdcmHeader::SetPubElValByName(std::string content, std::string tagName) {
+ //return ( PubElValSet.SetElValueByName (content, tagName) );
+ gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName);
+ if( dictEntry == NULL)
+ return false;
+ return(PubElValSet.SetElValueByNumber(content,
+ dictEntry->GetGroup(),
+ dictEntry->GetElement()));
}
/**
* @return 1 on success, 0 otherwise.
*/
-int gdcmHeader::SetPubElValLengthByNumber(guint32 length, guint16 group,
+bool gdcmHeader::SetPubElValLengthByNumber(guint32 length, guint16 group,
guint16 element) {
return ( PubElValSet.SetElValueLengthByNumber (length, group, element) );
}
-/**
- * \ingroup gdcmHeader
- * \brief Accesses an existing gdcmElValue in the ShaElValSet of this instance
- * 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 ElVal to modify
- * @param element element of the ElVal to modify
- * @return 1 on success, 0 otherwise.
- */
-int gdcmHeader::SetShaElValByNumber(std::string content,
- guint16 group, guint16 element) {
- return ( ShaElValSet.SetElValueByNumber (content, group, element) );
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Accesses an existing gdcmElValue in the ShaElValSet of this instance
- * through tag name and modifies it's content with the given value.
- * @param content new value to substitute with
- * @param ShadowTagName name of the tag to be modified
- */
-int gdcmHeader::SetShaElValByName(std::string content, std::string ShadowTagName) {
- return ( ShaElValSet.SetElValueByName (content, ShadowTagName) );
-}
-
/**
* \ingroup gdcmHeader
* \brief Parses the header of the file but WITHOUT loading element values.
* false otherwise.
*/
bool gdcmHeader::IsReadable(void) {
- if ( GetElValByName("Image Dimensions") != GDCM_UNFOUND
- && atoi(GetElValByName("Image Dimensions").c_str()) > 4 ) {
- return false;
+ std::string res = GetPubElValByNumber(0x0028, 0x0005);
+ if ( res != GDCM_UNFOUND
+ && atoi(res.c_str()) > 4 ) {
+ return false; // Image Dimensions
}
- if ( GetElValByName("Bits Allocated") == GDCM_UNFOUND )
- return false;
- if ( GetElValByName("Bits Stored") == GDCM_UNFOUND )
- return false;
- if ( GetElValByName("High Bit") == GDCM_UNFOUND )
- return false;
- if ( GetElValByName("Pixel Representation") == GDCM_UNFOUND )
- return false;
+ if ( GetPubElValByNumber(0x0028, 0x0100) == GDCM_UNFOUND )
+ return false; // "Bits Allocated"
+ if ( GetPubElValByNumber(0x0028, 0x0101) == GDCM_UNFOUND )
+ return false; // "Bits Stored"
+ if ( GetPubElValByNumber(0x0028, 0x0102) == GDCM_UNFOUND )
+ return false; // "High Bit"
+ if ( GetPubElValByNumber(0x0028, 0x0103) == GDCM_UNFOUND )
+ return false; // "Pixel Representation"
return true;
}
* \brief
* @return integer, acts as a Boolean
*/
-int gdcmHeader::Write(FILE * fp, FileType type) {
+bool gdcmHeader::Write(FILE * fp, FileType type) {
// TODO : move the following lines (and a lot of others, to be written)
// to a future function CheckAndCorrectHeader
* @return The encountered size when found, 1 by default.
*/
int gdcmHeader::GetZSize(void) {
- // Both in DicomV3 and ACR/Nema the consider the "Number of Frames"
+ // Both DicomV3 and ACR/Nema consider the "Number of Frames"
// as the third dimension.
std::string StrSize = GetPubElValByNumber(0x0028,0x0008);
if (StrSize != GDCM_UNFOUND)
*/
std::string gdcmHeader::GetPixelType(void) {
std::string BitsAlloc;
- BitsAlloc = GetElValByName("Bits Allocated");
+ BitsAlloc = GetPubElValByNumber(0x0028, 0x0100); // Bits Allocated
if (BitsAlloc == GDCM_UNFOUND) {
dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
BitsAlloc = std::string("16");
BitsAlloc = std::string("8"); // by old RGB images)
std::string Signed;
- Signed = GetElValByName("Pixel Representation");
+ Signed = GetPubElValByNumber(0x0028, 0x0103); // "Pixel Representation"
if (Signed == GDCM_UNFOUND) {
dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
BitsAlloc = std::string("0");
* @return int acts as a Boolean
*/
-int gdcmHeader::HasLUT(void) {
+bool gdcmHeader::HasLUT(void) {
// Check the presence of the LUT Descriptors
if (GetPubElValByNumber(0x0028,0x1101) == GDCM_UNFOUND)
- return 0;
+ return false;
// LutDescriptorGreen
if (GetPubElValByNumber(0x0028,0x1102) == GDCM_UNFOUND)
- return 0;
+ return false;
// LutDescriptorBlue
if (GetPubElValByNumber(0x0028,0x1103) == GDCM_UNFOUND)
- return 0;
+ return false;
// It is not enough
// we check also
if (GetPubElValByNumber(0x0028,0x1201) == GDCM_UNFOUND)
- return 0;
+ return false;
if (GetPubElValByNumber(0x0028,0x1202) == GDCM_UNFOUND)
- return 0;
+ return false;
if (GetPubElValByNumber(0x0028,0x1203) == GDCM_UNFOUND)
- return 0;
- return 1;
+ return false;
+ return true;
}
/**
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
// if it works, we shall have to check the 3 Palettes
}
+
+
+
+
+
+
+/**
+ * \ingroup gdcmHeader
+ * \brief Searches within the public dictionary 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.
+ */
+ gdcmElValue* gdcmHeader::GetElementByName(std::string tagName) {
+ gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName);
+ if( dictEntry == NULL)
+ return (gdcmElValue*)NULL;
+ return(PubElValSet.GetElementByNumber(dictEntry->GetGroup(),
+ dictEntry->GetElement()));
+}
+
+
+
+/**
+ * \ingroup gdcmElValSet
+ * \brief Sets the value (string) of the target Dicom Element
+ * @param content string value of the Dicom Element
+ * @param tagName name of the searched Dicom Element.
+ * @return true when found
+ */
+bool gdcmHeader::SetElValueByName(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 ( ! PubElValSet.GetTagHt().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);
+ gdcmElValue * a;
+ IterHT p;
+ TagElValueHT::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 = ((PubElValSet.GetTagHt().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;
+}
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.h,v 1.46 2004/01/12 13:12:28 regrain Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.h,v 1.47 2004/01/13 11:32:30 jpr Exp $
#ifndef GDCMHEADER_H
#define GDCMHEADER_H
/// 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;
- /// 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
/// ELement VALueS parsed with the PUBlic dictionary.
gdcmElValSet PubElValSet;
- /// ELement VALueS parsed with the SHAdow dictionary.
- gdcmElValSet ShaElValSet;
+
/// Refering underlying filename.
std::string filename;
gdcmElValue *ReadNextElement(void);
gdcmElValue *NewElValueByNumber(guint16 group, guint16 element);
gdcmElValue *NewElValueByName (std::string Name);
+
+ gdcmElValue* GetElementByName (std::string Name);
+ // moved from gdcmElValSet
void FindLength (gdcmElValue *);
void FindVR (gdcmElValue *);
void SkipBytes(guint32);
protected:
- FileType filetype;
FILE * fp;
-
+ FileType filetype; // ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
+
gdcmElValue * GetElValueByNumber(guint16 group, guint16 element);
- int CheckIfExistByNumber(guint16 Group, guint16 Elem );
+ bool CheckIfExistByNumber(guint16 Group, guint16 Elem );
int write(std::ostream&);
int anonymize(std::ostream&); // FIXME : anonymize should be a friend ?
virtual ~gdcmHeader();
- std::string GetFileName(void) {return filename;}
+ inline std::string GetFileName(void) {return filename;}
size_t GetPixelOffset(void);
size_t GetPixelAreaLength(void);
- int GetSwapCode(void) { return sw; }
-
- // TODO Swig int SetPubDict(std::string filename);
+ inline int GetSwapCode(void) { return sw; }
+
// When some proprietary shadow groups are disclosed, we can set up
// an additional specific dictionary to access extra information.
+
+ // OK : we still have *ONE* ElValSet,
+ // with both Public and Shadow Elements
+ // parsed against THE Public Dictionary and A (single) Shadow Dictionary
+
// TODO Swig int SetShaDict(std::string filename);
+ // TODO Swig int SetPubDict(std::string filename);
- std::string GetPubElValByName (std::string TagName);
- std::string GetPubElValRepByName (std::string TagName);
+ std::string GetPubElValByName (std::string tagName);
+ std::string GetPubElValRepByName (std::string tagName);
std::string GetPubElValByNumber (guint16 group, guint16 element);
std::string GetPubElValRepByNumber(guint16 group, guint16 element);
- size_t GetPubElValOffsetByNumber(guint16 Group, guint16 Elem);
+ size_t GetPubElValOffsetByNumber (guint16 Group, guint16 Elem);
void * GetPubElValVoidAreaByNumber(guint16 Group, guint16 Elem);
- void * LoadElementVoidArea(guint16 Group, guint16 Element);
+ void * LoadElementVoidArea (guint16 Group, guint16 Element);
+
+ inline ListTag & GetListElem(void) { return PubElValSet.GetListElem();};
+ inline TagElValueHT & GetPubElVal(void) { return PubElValSet.GetTagHt(); };
- ListTag & GetListElem(void) { return PubElValSet.GetListElem(); };
-
- TagElValueHT & GetPubElVal(void) { return PubElValSet.GetTagHt(); };
void PrintPubElVal(std::ostream & os = std::cout);
void PrintPubDict (std::ostream & os = std::cout);
-
- // TODO Swig std::string* GetShaTagNames();
- std::string GetShaElValByName (std::string TagName);
- std::string GetShaElValRepByName (std::string TagName);
- std::string GetShaElValByNumber (guint16 group, guint16 element);
- std::string GetShaElValRepByNumber(guint16 group, guint16 element);
-
- std::string GetElValByName (std::string TagName);
- std::string GetElValRepByName (std::string TagName);
- std::string GetElValByNumber (guint16 group, guint16 element);
- std::string GetElValRepByNumber(guint16 group, guint16 element);
- int SetPubElValByName (std::string content, std::string TagName);
- int SetShaElValByName (std::string content, std::string ShadowTagName);
-
- int SetPubElValByNumber(std::string content, guint16 group, guint16 element);
- int SetShaElValByNumber(std::string content, guint16 group, guint16 element);
-
- int SetPubElValLengthByNumber(guint32 lgr, guint16 group, guint16 element);
-
- int ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem);
- int ReplaceOrCreateByNumber( char * Value, guint16 Group, guint16 Elem);
- int ReplaceIfExistByNumber ( char * Value, guint16 Group, guint16 Elem);
+ bool SetPubElValByName (std::string content, std::string tagName);
+ bool SetPubElValByNumber(std::string content, guint16 group, guint16 element);
+ bool SetPubElValLengthByNumber(guint32 lgr, guint16 group, guint16 element);
+
+ std::string GetElValByName (std::string tagName);
+ std::string GetElValRepByName (std::string tagName);
+ std::string GetElValByNumber (guint16 group, guint16 element);
+ std::string GetElValRepByNumber(guint16 group, guint16 element);
+
+ bool SetElValueByName(std::string content,std::string tagName);
+ // moved from ElValSet
+
+ 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);
- int Write(FILE *, FileType);
+ bool Write(FILE *, FileType);
// Some heuristic based accessors, end user intended
+ // (to be move to gdcmHeaderHelper?)
int GetXSize(void);
int GetYSize(void);
int GetZSize(void);
int GetBitsStored(void);
int GetBitsAllocated(void);
- int GetSamplesPerPixel(void);
-
+ int GetSamplesPerPixel(void);
int GetPlanarConfiguration(void);
-
- int GetPixelSize(void);
+ int GetPixelSize(void);
+
std::string GetPixelType(void);
std::string GetTransferSyntaxName(void);
- int HasLUT(void);
+ bool HasLUT(void);
int GetLUTNbits(void);
unsigned char * GetLUTRGBA(void);
-
+
+ // voir gdcmFile::SetImageData ?!?
void SetImageDataSize (size_t ExpectedSize);
// System access
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.cxx,v 1.17 2003/11/12 14:06:35 malaterre Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.cxx,v 1.18 2004/01/13 11:32:30 jpr Exp $
#include "gdcmHeaderHelper.h"
*/
std::string gdcmHeaderHelper::GetPixelType() {
std::string BitsAlloc;
- BitsAlloc = GetElValByName("Bits Allocated");
- if (BitsAlloc == GDCM_UNFOUND) {
+ BitsAlloc = GetPubElValByNumber(0x0028, 0x0100);
+ if (BitsAlloc == GDCM_UNFOUND) { // Bits Allocated
dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
BitsAlloc = std::string("16");
}
BitsAlloc = std::string("8"); // by old RGB images)
std::string Signed;
- Signed = GetElValByName("Pixel Representation");
- if (Signed == GDCM_UNFOUND) {
+ Signed = GetPubElValByNumber(0x0028, 0x0103);
+ if (Signed == GDCM_UNFOUND) { // "Pixel Representation"
dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
BitsAlloc = std::string("0");
}
* @return Z dimension of a voxel-to be
*/
float gdcmHeaderHelper::GetZSpacing() {
- // TODO : translate into English
// Spacing Between Slices : distance entre le milieu de chaque coupe
// Les coupes peuvent etre :
// jointives (Spacing between Slices = Slice Thickness)
-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.h,v 1.9 2004/01/12 13:12:28 regrain Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.h,v 1.10 2004/01/13 11:32:30 jpr Exp $
#ifndef GDCMHEADERHELPER_H
#define GDCMHEADERHELPER_H
public:
gdcmHeaderHelper::gdcmHeaderHelper();
- gdcmHeaderHelper::gdcmHeaderHelper(const char *filename, bool exception_on_error = false);
+ gdcmHeaderHelper::gdcmHeaderHelper(const char *filename,
+ bool exception_on_error = false);
int GetPixelSize();
std::string GetPixelType();
*/
bool gdcmFile::ParsePixelData(void) {
+// DO NOT remove the printf s.
+// The ONLY purpose of this methos is to PRINT the content
+
FILE *fp;
if ( !(fp=Header->OpenFile()))
Header->IsDeflatedExplicitVRLittleEndianTransferSyntax() ) {
printf ("gdcmFile::ParsePixelData : non JPEG/RLE File\n");
- return 0;
+ return false;
}
int nb;
ftellRes,ItemTagGr,ItemTagEl );
}
}
- return 1;
+ return true;
}
/**
* \ingroup gdcmFile
* \brief Reads a 'Run Length Encoded' Dicom encapsulated file
+ * @param fp already open File Pointer
* @param image_buffer destination Address (in caller's memory space)
* at which the pixel data should be copied
*
- * @return int acts as a Boolean
+ * @return Boolean
*/
// This is a debug version.
from.getline(buff, 1024, '\n');
name = buff;
- if(key!="")
- {
+ if(key!="") {
ts[key]=name;
}
}
-// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.29 2003/12/22 12:46:19 regrain Exp $
+// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.30 2004/01/13 11:32:31 jpr Exp $
// //////////////////////////////////////////////////////////////
// WARNING TODO CLENAME
// Actual limitations of this code:
// But vtk chooses to invert the lines of an image, that is the last
// line comes first (for some axis related reasons?). Hence we need
// to load the image line by line, starting from the end.
+
int NumColumns = GdcmFile.GetHeader()->GetXSize();
int NumLines = GdcmFile.GetHeader()->GetYSize();
int NumPlanes = GdcmFile.GetHeader()->GetZSize();