+/**
+ * \brief Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries)
+ * @return length of the parsed set.
+ */
+
+long gdcmDocument::ParseDES(gdcmDocEntrySet *set,
+ long offset,
+ long l_max,
+ bool delim_mode)
+{
+ gdcmDocEntry *newDocEntry = 0;
+ unsigned long l = 0;
+
+ while (true)
+ {
+ if ( !delim_mode && (ftell(Fp)-offset) >= l_max)
+ {
+ break;
+ }
+ newDocEntry = ReadNextDocEntry( );
+ if ( !newDocEntry )
+ {
+ break;
+ }
+
+ gdcmVRKey vr = newDocEntry->GetVR();
+ if ( vr != "SQ" )
+ {
+
+ if ( gdcmGlobal::GetVR()->IsVROfGdcmStringRepresentable(vr) )
+ {
+ /////////////////////// ValEntry
+ gdcmValEntry* newValEntry =
+ new gdcmValEntry( newDocEntry->GetDictEntry() );
+ newValEntry->Copy( newDocEntry );
+
+ // When "set" is a gdcmDocument, then we are at the top of the
+ // hierarchy and the Key is simply of the form ( group, elem )...
+ if (gdcmDocument* dummy = dynamic_cast< gdcmDocument* > ( set ) )
+ {
+ (void)dummy;
+ newValEntry->SetKey( newValEntry->GetKey() );
+ }
+ // ...but when "set" is a gdcmSQItem, we are inserting this new
+ // valEntry in a sequence item. Hence the key has the
+ // generalized form (refer to \ref gdcmBaseTagKey):
+ if (gdcmSQItem* parentSQItem = dynamic_cast< gdcmSQItem* > ( set ) )
+ {
+ newValEntry->SetKey( parentSQItem->GetBaseTagKey()
+ + newValEntry->GetKey() );
+ }
+
+ set->AddEntry( newValEntry );
+ LoadDocEntry( newValEntry );
+ if (newValEntry->IsItemDelimitor())
+ {
+ break;
+ }
+ if ( !delim_mode && (ftell(Fp)-offset) >= l_max)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if ( ! gdcmGlobal::GetVR()->IsVROfGdcmBinaryRepresentable(vr) )
+ {
+ ////// Neither ValEntry NOR BinEntry: should mean UNKOWN VR
+ dbg.Verbose(0, "gdcmDocument::ParseDES: neither Valentry, "
+ "nor BinEntry. Probably unknown VR.");
+ }
+
+ //////////////////// BinEntry or UNKOWN VR:
+ gdcmBinEntry* newBinEntry =
+ new gdcmBinEntry( newDocEntry->GetDictEntry() );
+ newBinEntry->Copy( newDocEntry );
+
+ // When "this" is a gdcmDocument the Key is simply of the
+ // form ( group, elem )...
+ if (gdcmDocument* dummy = dynamic_cast< gdcmDocument* > ( set ) )
+ {
+ (void)dummy;
+ newBinEntry->SetKey( newBinEntry->GetKey() );
+ }
+ // but when "this" is a SQItem, we are inserting this new
+ // valEntry in a sequence item, and the kay has the
+ // generalized form (refer to \ref gdcmBaseTagKey):
+ if (gdcmSQItem* parentSQItem = dynamic_cast< gdcmSQItem* > ( set ) )
+ {
+ newBinEntry->SetKey( parentSQItem->GetBaseTagKey()
+ + newBinEntry->GetKey() );
+ }
+
+ set->AddEntry( newBinEntry );
+ LoadDocEntry( newBinEntry );
+ }
+
+ if (newDocEntry->GetGroup() == 0x7fe0 &&
+ newDocEntry->GetElement() == 0x0010 )
+ {
+ if (newDocEntry->GetReadLength()==0xffffffff)
+ {
+ // Broken US.3405.1.dcm
+ Parse7FE0(); // to skip the pixels
+ // (multipart JPEG/RLE are trouble makers)
+ }
+ else
+ {
+ SkipToNextDocEntry(newDocEntry);
+ l = newDocEntry->GetFullLength();
+ }
+ }
+ else
+ {
+ // to be sure we are at the beginning
+ SkipToNextDocEntry(newDocEntry);
+ l = newDocEntry->GetFullLength();
+ }
+ }
+ else
+ {
+ // VR = "SQ"
+ l = newDocEntry->GetReadLength();
+ if ( l != 0 ) // don't mess the delim_mode for zero-length sequence
+ {
+ if ( l == 0xffffffff )
+ {
+ delim_mode = true;
+ }
+ else
+ {
+ delim_mode = false;
+ }
+ }
+ // no other way to create it ...
+ gdcmSeqEntry* newSeqEntry =
+ new gdcmSeqEntry( newDocEntry->GetDictEntry() );
+ newSeqEntry->Copy( newDocEntry );
+ newSeqEntry->SetDelimitorMode( delim_mode );
+
+ // At the top of the hierarchy, stands a gdcmDocument. When "set"
+ // is a gdcmDocument, then we are building the first depth level.
+ // Hence the gdcmSeqEntry we are building simply has a depth
+ // level of one:
+ if (gdcmDocument* dummy = dynamic_cast< gdcmDocument* > ( set ) )
+ {
+ (void)dummy;
+ newSeqEntry->SetDepthLevel( 1 );
+ newSeqEntry->SetKey( newSeqEntry->GetKey() );
+ }
+ // But when "set" is allready a SQItem, we are building a nested
+ // sequence, and hence the depth level of the new gdcmSeqEntry
+ // we are building, is one level deeper:
+ if (gdcmSQItem* parentSQItem = dynamic_cast< gdcmSQItem* > ( set ) )
+ {
+ newSeqEntry->SetDepthLevel( parentSQItem->GetDepthLevel() + 1 );
+ newSeqEntry->SetKey( parentSQItem->GetBaseTagKey()
+ + newSeqEntry->GetKey() );
+ }
+
+ if ( l != 0 )
+ { // Don't try to parse zero-length sequences
+ (void)ParseSQ( newSeqEntry,
+ newDocEntry->GetOffset(),
+ l, delim_mode);
+ }
+ set->AddEntry( newSeqEntry );
+ if ( !delim_mode && (ftell(Fp)-offset) >= l_max)
+ {
+ break;
+ }
+ }
+ delete newDocEntry;
+ }
+ return l; // Probably useless
+}
+
+/**
+ * \brief Parses a Sequence ( SeqEntry after SeqEntry)
+ * @return parsed length for this level
+ */
+long gdcmDocument::ParseSQ( gdcmSeqEntry* seqEntry,
+ long offset, long l_max, bool delim_mode)
+{
+ int SQItemNumber = 0;
+ bool dlm_mod;
+
+ while (true)
+ {
+ gdcmDocEntry* newDocEntry = ReadNextDocEntry();
+ if ( !newDocEntry )
+ {
+ // FIXME Should warn user
+ break;
+ }
+ if( delim_mode )
+ {
+ if ( newDocEntry->IsSequenceDelimitor() )
+ {
+ seqEntry->SetSequenceDelimitationItem( newDocEntry );
+ break;
+ }
+ }
+ if ( !delim_mode && (ftell(Fp)-offset) >= l_max)
+ {
+ break;
+ }
+
+ gdcmSQItem *itemSQ = new gdcmSQItem( seqEntry->GetDepthLevel() );
+ std::ostringstream newBase;
+ newBase << seqEntry->GetKey()
+ << "/"
+ << SQItemNumber
+ << "#";
+ itemSQ->SetBaseTagKey( newBase.str() );
+ unsigned int l = newDocEntry->GetReadLength();
+
+ if ( l == 0xffffffff )
+ {
+ dlm_mod = true;
+ }
+ else
+ {
+ dlm_mod = false;
+ }
+
+ (void)ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod);
+
+ seqEntry->AddEntry( itemSQ, SQItemNumber );
+ SQItemNumber++;
+ if ( !delim_mode && ( ftell(Fp) - offset ) >= l_max )
+ {
+ break;
+ }
+ }
+
+ int lgth = ftell(Fp) - offset;
+ return lgth;
+}
+