Program: gdcm
Module: $RCSfile: gdcmDocument.cxx,v $
Language: C++
- Date: $Date: 2004/10/22 04:13:25 $
- Version: $Revision: 1.109 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.117 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
* \brief constructor
* @param filename file to be opened for parsing
*/
-Document::Document( std::string const & filename )
- : ElementSet(-1)
+Document::Document( std::string const & filename ) : ElementSet(-1)
{
SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
Filename = filename;
* \brief This default constructor doesn't parse the file. You should
* then invoke \ref Document::SetFileName and then the parsing.
*/
-Document::Document()
- :ElementSet(-1)
+Document::Document() : ElementSet(-1)
{
SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
Initialise();
if (filetype == ImplicitVR)
{
- std::string ts = TransferSyntaxStrings[ImplicitVRLittleEndian];
+ std::string ts =
+ Util::DicomString( TransferSyntaxStrings[ImplicitVRLittleEndian] );
ReplaceOrCreateByNumber(ts, 0x0002, 0x0010);
/// \todo Refer to standards on page 21, chapter 6.2
if (filetype == ExplicitVR)
{
- std::string ts = TransferSyntaxStrings[ExplicitVRLittleEndian];
+ std::string ts =
+ Util::DicomString( TransferSyntaxStrings[ExplicitVRLittleEndian] );
ReplaceOrCreateByNumber(ts, 0x0002, 0x0010);
/// \todo Refer to standards on page 21, chapter 6.2
std::string const & value,
uint16_t group,
uint16_t elem,
- std::string const & VR )
+ TagName const & vr )
{
ValEntry* valEntry = 0;
DocEntry* currentEntry = GetDocEntryByNumber( group, elem);
DictEntry* dictEntry = pubDict->GetDictEntryByNumber(group, elem);
if (!dictEntry)
{
- currentEntry = NewDocEntryByNumber(group, elem,VR);
+ currentEntry = NewDocEntryByNumber(group, elem, vr);
}
else
{
int lgth,
uint16_t group,
uint16_t elem,
- std::string const& VR )
+ TagName const & vr )
{
BinEntry* binEntry = 0;
DocEntry* currentEntry = GetDocEntryByNumber( group, elem);
if (!dictEntry)
{
- currentEntry = NewDocEntryByNumber(group, elem, VR);
+ currentEntry = NewDocEntryByNumber(group, elem, vr);
}
else
{
* \return pointer to the modified/created SeqEntry (NULL when creation
* failed).
*/
-SeqEntry* Document::ReplaceOrCreateByNumber(
- uint16_t group,
- uint16_t elem)
+SeqEntry* Document::ReplaceOrCreateByNumber( uint16_t group, uint16_t elem)
{
SeqEntry* b = 0;
DocEntry* a = GetDocEntryByNumber( group, elem);
* \return boolean
*/
bool Document::ReplaceIfExistByNumber(std::string const & value,
- uint16_t group, uint16_t elem )
+ uint16_t group, uint16_t elem )
{
SetEntryByNumber(value, group, elem);
bool Document::CheckIfEntryExistByNumber(uint16_t group, uint16_t element )
{
const std::string &key = DictEntry::TranslateToKey(group, element );
- return TagHT.count(key);
+ return TagHT.count(key) != 0;
}
/**
* @return Corresponding element value when it exists,
* and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
*/
-std::string Document::GetEntryByName(TagName const& tagName)
+std::string Document::GetEntryByName(TagName const & tagName)
{
DictEntry* dictEntry = RefPubDict->GetDictEntryByName(tagName);
if( !dictEntry )
}
DocEntry* elem = GetDocEntryByNumber(dictEntry->GetGroup(),
- dictEntry->GetElement());
+ dictEntry->GetElement());
return elem->GetVR();
}
* @param tagName name of the searched Dicom Element.
* @return true when found
*/
-bool Document::SetEntryByName(std::string const & content,std::string const & tagName)
+bool Document::SetEntryByName(std::string const & content,
+ TagName const & tagName)
{
DictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
if( !dictEntry )
* @param element element number of the Dicom Element to modify
*/
bool Document::SetEntryByNumber(std::string const& content,
- uint16_t group,
- uint16_t element)
+ uint16_t group, uint16_t element)
{
int c;
int l;
return false;
}
// Non even content must be padded with a space (020H)...
- std::string finalContent = content;
- if( finalContent.length() % 2 )
- {
- finalContent += '\0'; // ... therefore we padd with (000H) .!?!
- }
+ std::string finalContent = Util::DicomString( content.c_str() );
+ assert( !(finalContent.size() % 2) );
valEntry->SetValue(finalContent);
-
+
// Integers have a special treatement for their length:
l = finalContent.length();
* @param group group number of the Dicom Element to modify
* @param element element number of the Dicom Element to modify
*/
-bool Document::SetEntryByNumber(uint8_t*content,
- int lgth,
- uint16_t group,
- uint16_t element)
+bool Document::SetEntryByNumber(uint8_t*content, int lgth,
+ uint16_t group, uint16_t element)
{
(void)lgth; //not used
TagKey key = DictEntry::TranslateToKey(group, element);
* @return true on success, false otherwise.
*/
bool Document::SetEntryLengthByNumber(uint32_t l,
- uint16_t group,
- uint16_t element)
+ uint16_t group, uint16_t element)
{
/// \todo use map methods, instead of multimap JPR
TagKey key = DictEntry::TranslateToKey(group, element);
* @return
*/
bool Document::SetEntryBinAreaByNumber(uint8_t* area,
- uint16_t group,
- uint16_t element)
+ uint16_t group, uint16_t element)
{
DocEntry* currentEntry = GetDocEntryByNumber(group, element);
if ( !currentEntry )
* @return Corresponding Dicom Element when it exists, and NULL
* otherwise.
*/
-DocEntry* Document::GetDocEntryByName(std::string const & tagName)
+DocEntry* Document::GetDocEntryByName(TagName const & tagName)
{
DictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
if( !dictEntry )
* @param element Element number of the searched Dicom Element
* @return
*/
-DocEntry* Document::GetDocEntryByNumber(uint16_t group,
- uint16_t element)
+DocEntry* Document::GetDocEntryByNumber(uint16_t group, uint16_t element)
{
TagKey key = DictEntry::TranslateToKey(group, element);
if ( !TagHT.count(key))
* ValEntry.
* @return When present, the corresponding ValEntry.
*/
-ValEntry* Document::GetValEntryByNumber(uint16_t group,
- uint16_t element)
+ValEntry* Document::GetValEntryByNumber(uint16_t group, uint16_t element)
{
DocEntry* currentEntry = GetDocEntryByNumber(group, element);
if ( !currentEntry )
* \brief Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries)
* @return length of the parsed set.
*/
-void Document::ParseDES(DocEntrySet *set,
- long offset,
- long l_max,
- bool delim_mode)
+void Document::ParseDES(DocEntrySet *set, long offset,
+ long l_max, bool delim_mode)
{
DocEntry *newDocEntry = 0;
* @return parsed length for this level
*/
void Document::ParseSQ( SeqEntry* seqEntry,
- long offset, long l_max, bool delim_mode)
+ long offset, long l_max, bool delim_mode)
{
int SQItemNumber = 0;
bool dlm_mod;
}
// to be sure we are at the end of the value ...
- Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(),std::ios_base::beg);
+ Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(),
+ std::ios_base::beg);
return;
}
return;
}
- // We need an additional byte for storing \0 that is not on disk
+ // FIXME: We need an additional byte for storing \0 that is not on disk
char *str = new char[length+1];
Fp->read(str, (size_t)length);
- str[length] = '\0';
- std::string newValue = str;
+ str[length] = '\0'; //this is only useful when length is odd
+ // Special DicomString call to properly handle \0 and even length
+ std::string newValue;
+ if( length % 2 )
+ {
+ newValue = Util::DicomString(str, length+1);
+ //dbg.Verbose(0, "Warning: bad length: ", length );
+ dbg.Verbose(0, "For string :", newValue.c_str());
+ // Since we change the length of string update it length
+ entry->SetReadLength(length+1);
+ }
+ else
+ {
+ newValue = Util::DicomString(str, length);
+ }
delete[] str;
if ( ValEntry* valEntry = dynamic_cast<ValEntry* >(entry) )
- {
+ {
if ( Fp->fail() || Fp->eof())//Fp->gcount() == 1
{
dbg.Verbose(1, "Document::LoadDocEntry",
* @param foundLength fist assumption about length
*/
void Document::FixDocEntryFoundLength(DocEntry *entry,
- uint32_t foundLength)
+ uint32_t foundLength)
{
entry->SetReadLength( foundLength ); // will be updated only if a bug is found
if ( foundLength == 0xffffffff)
{
uint16_t element = entry->GetElement();
uint16_t group = entry->GetGroup();
- std::string vr = entry->GetVR();
+ const std::string & vr = entry->GetVR();
uint32_t length = entry->GetLength();
// When we have some semantics on the element we just read, and if we
Fp->read ((char*)&g, (size_t)2);
if ( Fp->fail() )
{
- throw FormatError( "Document::ReadInt16()", " file error." );
+ throw FormatError( "Document::ReadInt16()", " file error." );
}
if( Fp->eof() )
{
//// Read the Item Tag group and element, and make
// sure they are what we expected:
- uint16_t itemTagGroup = ReadInt16();
- uint16_t itemTagElement = ReadInt16();
+ uint16_t itemTagGroup;
+ uint16_t itemTagElement;
+ try
+ {
+ itemTagGroup = ReadInt16();
+ itemTagElement = ReadInt16();
+ }
+ catch ( FormatError e )
+ {
+ //std::cerr << e << std::endl;
+ return false;
+ }
if ( itemTagGroup != testGroup || itemTagElement != testElement )
{
std::ostringstream s;
long frameOffset = Fp->tellg();
uint32_t nbRleSegments = ReadInt32();
+ if ( nbRleSegments > 16 )
+ {
+ // There should be at most 15 segments (refer to RLEFrame class)
+ dbg.Verbose(0, "Document::ComputeRLEInfo: too many segments.");
+ }
uint32_t rleSegmentOffsetTable[15];
for( int k = 1; k <= 15; k++ )
* @param set The structure to be traversed (recursively).
*/
void Document::BuildFlatHashTableRecurse( TagDocEntryHT& builtHT,
- DocEntrySet* set )
+ DocEntrySet* set )
{
if (ElementSet* elementSet = dynamic_cast< ElementSet* > ( set ) )
{
- TagDocEntryHT* currentHT = elementSet->GetTagHT();
- for( TagDocEntryHT::const_iterator i = currentHT->begin();
- i != currentHT->end();
+ TagDocEntryHT const & currentHT = elementSet->GetTagHT();
+ for( TagDocEntryHT::const_iterator i = currentHT.begin();
+ i != currentHT.end();
++i)
{
DocEntry* entry = i->second;
if ( SeqEntry* seqEntry = dynamic_cast<SeqEntry*>(entry) )
{
- ListSQItem& items = seqEntry->GetSQItems();
+ const ListSQItem& items = seqEntry->GetSQItems();
for( ListSQItem::const_iterator item = items.begin();
item != items.end();
++item)
if (SQItem* SQItemSet = dynamic_cast< SQItem* > ( set ) )
{
- ListDocEntry& currentList = SQItemSet->GetDocEntries();
- for (ListDocEntry::iterator i = currentList.begin();
- i != currentList.end();
- ++i)
+ const ListDocEntry& currentList = SQItemSet->GetDocEntries();
+ for (ListDocEntry::const_iterator i = currentList.begin();
+ i != currentList.end();
+ ++i)
{
DocEntry* entry = *i;
if ( SeqEntry* seqEntry = dynamic_cast<SeqEntry*>(entry) )
{
- ListSQItem& items = seqEntry->GetSQItems();
+ const ListSQItem& items = seqEntry->GetSQItems();
for( ListSQItem::const_iterator item = items.begin();
item != items.end();
++item)