//-----------------------------------------------------------------------------
// Public
-//bool gdcmDocEntrySet::AddEntry(gdcmDocEntry *Entry){return true;}
//-----------------------------------------------------------------------------
// Protected
//-----------------------------------------------------------------------------
// Private
-/**
- * \brief Parses an EntrySet (Document header or SQ Item )
- * \ and load element values (a voir !)
- * @return false anything wrong happens
- */
-
- /* just to keep the code
-
-bool gdcmDocEntrySet::LoadDocEntrySet(bool exception_on_error)
- throw(gdcmFormatError) {
- (void)exception_on_error;
-
- gdcmDocEntry *newDocEntry = (gdcmDocEntry *)0;
- gdcmValEntry *newValEntry = (gdcmValEntry *)0;
- gdcmBinEntry *newBinEntry = (gdcmBinEntry *)0;
- gdcmSeqEntry *newSeqEntry = (gdcmSeqEntry *)0;
-
- string vr;
- while (newDocEntry = ReadNextDocEntry()) {
- // TODO (?) : liberation du DocEntry ainsi cree,
- // apres copie dans un ValEntry, SeqEntry, BinEntry
- vr = newDocEntry->GetVR();
-
- if (vr == "SQ" ) {
- // --- SeqEntry
-
- newSeqEntry = new gdcmSeqEntry((gdcmDictEntry*)NULL);
- if (!newSeqEntry) {
- dbg.Verbose(1, "gdcmDocEntrySet::LoadDocEntrySet",
- "failed to allocate gdcmSeqEntry");
- return false;
- }
- newSeqEntry->Copy(newDocEntry);
- // TODO
- // SEQUENCE; appel 'récursif' de ??? pour charger la 'valeur'
- // (ensemble d' ITEMs, en fait,
- // chaque ITEM etant chargé avec LoadDocEntrySet)
-
- //SkipDocEntry(newSeqEntry); // voir ce qu'on fait pour une SeQuence
- AddEntry(newSeqEntry); // on appele la fonction generique,
- // ou une fonction spécialisée ?
-
- } else if (vr == "AE" || vr == "AS" || vr == "DA" || vr == "PN" ||
- vr == "UI" || vr == "TM" || vr == "SH" || vr == "LO" ||
- vr == "CS" || vr == "IS" || vr == "LO" || vr == "LT" ||
- vr == "SH" || vr == "ST" ||
- vr == "SL" || vr == "SS" || vr == "UL" || vr == "US"
- ) {
- // --- ValEntry
-
- newValEntry = new gdcmValEntry((gdcmDictEntry*)NULL);
- if (!newValEntry) {
- dbg.Verbose(1, "gdcmDocEntrySet::LoadDocEntrySet",
- "failed to allocate gdcmValEntry");
- return false;
- }
- newValEntry->Copy(newDocEntry);
- //SkipDocEntry(newValEntry); //le skip devrait etre fait dans le Read
- AddEntry(newValEntry); // on appele la fonction generique,
- // ou une fonction spécialisée ?
-
- // Maybe the following VR do correspond to a BinEntry
-
- //AT Attribute Tag; // 2 16-bit unsigned short integers
- //FL Floating Point Single; // 32-bit IEEE 754:1985 float
- //FD Floating Point Double; // 64-bit IEEE 754:1985 double
- //UN Unknown; // Any length of bytes
- //UT Unlimited Text; // At most 2^32 -1 chars
- //OB Other Byte String; // String of bytes (VR independant)
- //OW Other Word String; // String of 16-bit words (VR dependant)
- } else {
- // --- BinEntry
-
- newBinEntry = new gdcmBinEntry((gdcmDictEntry*)NULL);
- if (!newBinEntry) {
- dbg.Verbose(1, "gdcmDocEntrySet::LoadDocEntrySet",
- "failed to allocate gdcmBinEntry");
- return false;
- }
- newBinEntry->Copy(newDocEntry);
- // SkipDocEntry(newBinEntry); //le skip devrait etre fait dans le Read
- AddEntry(newBinEntry); // on appele la fonction generique,
- // ou une fonction spécialisée ?
- }
- }
-
-
-
- // TODO : il n'y a plus de Chained List qui contient toutes les Entries
- // Le chargement des valeurs devra se faire à la volée
- // Be carefull : merging this two loops may cause troubles ...
-
-/*
- rewind(fp);
- for (ListTag::iterator i = GetListEntry().begin();
- i != GetListEntry().end();
- ++i)
- {
- LoadDocEntry(*i);
- }
- rewind(fp);
-
- */
-
- /* TO DO : deporter den fin de parsing du DOCUMENT (pas du EntrySet)
-
- // --------------------------------------------------------------
- // Special Patch to allow gdcm to read ACR-LibIDO formated images
- //
- // if recognition code tells us we deal with a LibIDO image
- // we switch lineNumber and columnNumber
- //
- std::string RecCode;
- RecCode = GetEntryByNumber(0x0008, 0x0010); // recognition code
- if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
- RecCode == "CANRME_AILIBOD1_1." ) // for brain-damaged softwares
- // with "little-endian strings"
- {
- filetype = ACR_LIBIDO;
- std::string rows = GetEntryByNumber(0x0028, 0x0010);
- std::string columns = GetEntryByNumber(0x0028, 0x0011);
- SetEntryByNumber(columns, 0x0028, 0x0010);
- SetEntryByNumber(rows , 0x0028, 0x0011);
- }
- // ----------------- End of Special Patch ----------------
- */
-
- /*
- return true;
-}
-
-*/
-
-
//-----------------------------------------------------------------------------
long l=ParseDES( this, beg, lgt, false); // le Load sera fait a la volee
CloseFile();
+ /* TO DO : uncomment when everything else is OK
+
+ // --------------------------------------------------------------
+ // Special Patch to allow gdcm to read ACR-LibIDO formated images
+ //
+ // if recognition code tells us we deal with a LibIDO image
+ // we switch lineNumber and columnNumber
+ //
+ std::string RecCode;
+ RecCode = GetEntryByNumber(0x0008, 0x0010); // recognition code
+ if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
+ RecCode == "CANRME_AILIBOD1_1." ) // for brain-damaged softwares
+ // with "little-endian strings"
+ {
+ filetype = ACR_LIBIDO;
+ std::string rows = GetEntryByNumber(0x0028, 0x0010);
+ std::string columns = GetEntryByNumber(0x0028, 0x0011);
+ SetEntryByNumber(columns, 0x0028, 0x0010);
+ SetEntryByNumber(rows , 0x0028, 0x0011);
+ }
+ // ----------------- End of Special Patch ----------------
+ */
+
+
printLevel = 1; // 'Medium' print level by default
}
gdcmBinEntry *bn;
gdcmSeqEntry *sq;
string vr;
- long l;
+ long l;
+ cout << hex << "offset " << offset
+ << " l_max "<< l_max
+ << " ftell a l'entree " << ftell(fp)
+ << endl;
while (true) {
NewDocEntry = ReadNextDocEntry( );
if (!NewDocEntry)
break;
- std::cout << hex << NewDocEntry->GetGroup()
- << " "
+ std::cout << hex
+ << " gr "
+ << NewDocEntry->GetGroup()
+ << " el "
<< NewDocEntry->GetElement()
- << " "
+ << " vr "
<< NewDocEntry->GetVR()
- << " "
+ << " lgt "
<< NewDocEntry->GetReadLength()
- << " "
+ << " off "
<< NewDocEntry->GetOffset()
<< std::endl;
set->AddEntry(vl);
LoadDocEntry(vl);
std::cout << "value [" << vl->GetValue() << "]" << std::endl;
- if (!delim_mode && vl->isItemDelimitor())
+ if (/*!delim_mode && */vl->isItemDelimitor())
break;
+ cout << hex
+ << " l_max = "<< l_max
+ << " offset = " << offset
+ << " ftell(fp) = " << ftell(fp)
+ << endl;
+ if ( !delim_mode && ftell(fp)-offset >= l_max)
+ break;
} else { // BinEntry
// Hope the following VR *do* correspond to a BinEntry
std::cout << "value [" << "Bin Entry, in voidArea" << "]" << std::endl;
}
- SkipToNextDocEntry(NewDocEntry); // to be sure to be at the beginning
+ SkipToNextDocEntry(NewDocEntry); // to be sure we are at the beginning
l = NewDocEntry->GetFullLength();
} else { // VR = "SQ"
-
- //SkipDocEntry(NewDocEntry);
-
+
std::cout << "gdcmDocument::ParseDES : SQ found " << std::endl;
- l=NewDocEntry->GetReadLength();
+ l=NewDocEntry->GetReadLength();
+
if (l == 0xffffffff)
delim_mode = true;
else
delim_mode = false;
+
sq = new gdcmSeqEntry(NewDocEntry->GetDictEntry());
sq->Copy(NewDocEntry);
sq->SetDelimitorMode(delim_mode);
- long lgt = ParseSQ((gdcmDocEntrySet *)sq, offset, l, delim_mode);
+
+ if (l != 0) { // Don't try to parse zero-length sequences
+ long lgt = ParseSQ((gdcmDocEntrySet *)sq,
+ //NewDocEntry->GetOffset(),
+ offset, // marche pour DICOMDIR, plante sur 3...dcm
+ l, delim_mode);
+ }
// FIXME : on en fait quoi, de lgt ?
set->AddEntry(sq);
+ cout << " l_max = " << l_max
+ << " offset = " << offset
+ << "ftell(fp) = " << ftell(fp)
+ << endl;
if ( !delim_mode && ftell(fp)-offset >= l_max)
break;
}
return l; // ??
}
-
-
/**
* \brief Parses a Sequence ( SeqEntry after SeqEntry)
* @return parsed length for this level
*/
-
-
long gdcmDocument::ParseSQ(gdcmDocEntrySet *set, long offset, long l_max, bool delim_mode) {
- std::cout << "Entree ds gdcmDocument::ParseSQ" << std::endl;
-
+ cout << "=================== gdcmDocument::ParseSQ on entre ds une Sequence"
+ << hex
+ << " offset " << offset
+ << " l_max " << l_max
+ << " delim_mode " << delim_mode
+ <<endl;
+ int SQItemNumber = 0;
gdcmDocEntry *NewDocEntry = (gdcmDocEntry *)0;
gdcmSQItem *itemSQ;
bool dlm_mod;
int lgr, l, lgth;
- cout << "=============== on entre ds une Sequence" <<endl;
while (true) {
- std::cout << "gdcmDocument::ParseSQ on itere" << std::endl;
-
+ std::cout << " ===== gdcmDocument::ParseSQ on itere "
+ << "sur les SQ Items : num "
+ << SQItemNumber << std::endl;
+
+ NewDocEntry = ReadNextDocEntry();
+cout << "=============================== isSequenceDelimitor "
+ << NewDocEntry->isSequenceDelimitor()
+ << endl;
if(delim_mode) {
- NewDocEntry = ReadNextDocEntry();
if (NewDocEntry->isSequenceDelimitor()) {
+ cout << " SequenceDelimitationItem found" << endl;
// add the Sequence Delimitor // TODO : find the trick to put it proprerly !
// ((gdcmSeqEntry *)set)->SetSequenceDelimitationItem(NewDocEntry);
break;
}
}
- if (!delim_mode && (ftell(fp)-offset) >= l_max){
+ if (!delim_mode && (ftell(fp)-offset) >= l_max) {
+ cout << hex
+ << " offset " << offset
+ << " l_max " << l_max
+ << " ftell " << ftell(fp)
+ << endl;
+ cout << "depasse ou atteint : on sort " << endl;
break;
}
itemSQ = new gdcmSQItem();
itemSQ->AddEntry(NewDocEntry); // no value, no voidArea. Think of it while printing !
- l= NewDocEntry->GetLength();
+ l= NewDocEntry->GetReadLength();
+ cout << "NewDocEntry->GetReadLength() " << l << endl;
if (l ==0xffffffff)
dlm_mod = true;
else
dlm_mod=false;
-
- lgr=ParseDES(itemSQ, offset, l, dlm_mod);
+cout << "================================ appel ParseDES :dlm_mod = " << dlm_mod <<endl;
+ lgr=ParseDES(itemSQ, NewDocEntry->GetOffset(), l, dlm_mod);
((gdcmSeqEntry *)set)->AddEntry(itemSQ);
+cout << "================================ sortie ParseDES " << endl;
+ SQItemNumber ++;
}
//Update(lgth);
lgth = ftell(fp) - offset;
// Public
bool gdcmSQItem::AddEntry(gdcmDocEntry *entry) {
- std::cout << " entree ds gdcmSQItem::AddEntry" << std::endl;
+ std::cout << " === entree ds gdcmSQItem::AddEntry "
+ << hex << entry->GetGroup()
+ << " "
+ << entry->GetElement()
+ << " lgt "
+ << entry->GetReadLength()
+ << std::endl;
+
docEntries.push_back(entry);
//TODO : check if it worked
return true;
private:
// DocEntry related utilities
-
-
+
virtual gdcmDocEntry *NewDocEntryByNumber(guint16 group,
guint16 element);
virtual gdcmDocEntry *NewDocEntryByName (std::string Name);
/// \brief chained list of (Elementary) Doc Entries
ListDocEntry docEntries;
+/// \brief SQ Item ordinal number
+ int SQItemNumber;
};
gdcmSeqEntry::gdcmSeqEntry(gdcmDictEntry* e)
: gdcmDocEntry(e)
{
- //ListSQItem items est un *champ* de gdcmSeqEntry.
-
delimitor_mode = false;
seq_term = NULL;
}
{
delete *cc;
}
+ if (!seq_term)
+ delete seq_term;
}
//-----------------------------------------------------------------------------
}
// at end, print the sequence terminator item, if any
/*
- if (delimitor_mode) {
+ if (delimitor_mode) { // TODO : find the trick to print it properly
s << " | " ;
os << s.str();
if (seq_term = NULL)
//-----------------------------------------------------------------------------
// Protected
+
//-----------------------------------------------------------------------------
// Private